2016-09-19 55 views
6

Benim SFINAE kodu değil, ancak MSVC 2013MSVC 2013 'türü': <code>std::enable_if</code> GCC & Clang içinde derler kullanarak std' üyesi :: enable_if <false,void>

kodu (also available on cpp.sh)

olduğunu GCC/Clang yılında
#include <iostream> 
#include <type_traits> 

template <typename T, typename ... AdditionalInputs> 
typename std::enable_if<sizeof...(AdditionalInputs) == 0, void>::type 
CallDoDataProcessing(T var) { 
    std::cout << sizeof...(AdditionalInputs) << " additional inputs" << std::endl; 
} 

template <typename T, typename ... AdditionalInputs> 
typename std::enable_if<sizeof...(AdditionalInputs) == 1, void>::type 
CallDoDataProcessing(T var) { 
    std::cout << sizeof...(AdditionalInputs) << " additional inputs" << std::endl; 
} 

int main() { 
    CallDoDataProcessing<int>(3); 
    CallDoDataProcessing<int, int>(3); 
    return 0; 
} 

bu olsa MSVC, mükemmel çalışıyor, ben alıyorum:

Error 1 error C2039: 'type' : is not a member of 'std::enable_if<false,void>' c:\Users\mrussell\documents\visual studio 2013\Projects\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp 5 1 ConsoleApplication1 

derlenmiş ve çalıştırmak çıkış olmalıdır:

0 additional inputs 
1 additional inputs 

SO ile ilgili bazı benzer sorunları gördüm, ancak hiçbiri net bir cevaba sahip değildi ya da biraz bronzlaşmıştı.

MSVC enable_if sayfayı okuma, bu çalışması gerekir ...

nasıl MSVC2013 içinde SFINAE kullanabiliriz?

Sadece bir not olarak

GÜNCELLEME, olumlu durumda bunu yapar çalışır. Örneğin, ilk işlevi ve buna çağrıyı söylersem, geri kalanı derler. yani CallDoDataProcessing'daki enable_if<true, void>, type üyesine sahiptir. 'sizeof...(AdditionalInputs) == 0 olsa çalışmaz sürümünü bırakarak, bu yüzden (buna diyoruz. Aynı hata.

Bu sizeof...(AdditionalInputs) == 0 çağrı eşleşti ediliyor olmadığını göstermektedir, ancak can ve ikinci fonksiyonu dışında yorum Ancak

, t o olmaz anlamaya.

+0

'lü # içdeydiniz mi? – AndyG

+0

@AndyG Bunu hiç düşünmemiştim, sadece denedim ve fark yaratmıyor gibiydi. Dahil olanı göstermek için yukarıdaki kodu değiştireceğim. – Matt

+1

İlk tahminim MSVC'yi güncellemeniz gerektiğidir. –

cevap

5

deneyin etiketi gönderilmesi.

template<std::size_t> 
struct size {}; 

namespace details { 
    template <typename T, typename ... AdditionalInputs> 
    void CallDoDataProcessing(T var, size<0>) { 
    std::cout << sizeof...(AdditionalInputs) << ", aka 0, additional inputs" << std::endl; 
    } 

    template <typename T, typename ... AdditionalInputs, std::size_t N> 
    void CallDoDataProcessing(T var, size<N>) { 
    std::cout << sizeof...(AdditionalInputs) << " additional inputs" << std::endl; 
    } 
} 
template <typename T, typename ... AdditionalInputs> 
void CallDoDataProcessing(T var) { 
    details::CallDoDataProcessing<T, AdditionalInputs>(var, size<sizeof...(AdditionalInputs)>{}); 
} 

SFINAE gerçekten kötü MSVC tarafından desteklenmektedir. Kodunuz geçerli SFINAE benziyor. MSVC doğru olanı yapmak başarısız olduğu gerçeğini n Şaşırtıcı.

MSVC çok fazla deneyimimle etiket gönderip daha iyi ve hatta bazen kod ve hatta bazen hata iletilerini anlamak daha kolay sonuçlar buluyorum.

İzin vermediği, arama işlevinin gövdesinden önce "hayır, bunu yapamazsınız", çağrı işlevinin "hayır, yapılamam" durumunu bildirmesidir.

+0

Güzel! İlk başta, bu, 'Ek Girişler' 0 veya 1 olmakla sınırlandıracağını düşündüm, ama ben [N girdisi ile çalışan bir örnek yazdım] (http://cpp.sh/82nwr) – Matt

+1

@MASINE geri düştünüz Orada enable_if şeyler. Yine, MSVC, SFINAE'yi çok iyi yapmıyor. Şaşırtıcı olmayan değişikliklerden, şifrelenmemiş değişikliklerden, şaşırtıcı şekillerde kopabilir. Eğer 'N'' 1' veya '2' olmasını istiyorsanız,' <1>' veya '<2>' boyutlarını kullanın,' N' ve ardından SFINAE 'N'' 1' veya '2 olmalıdır. '. Ardından, ihtiyacınız varsa "özel durumlarınızın üstündeki her şeyi" ele alan bir "N" jenerik bırakın. (Tabii ki, ideal olanı her davayı halledebilirdi, ama ...) – Yakk

+0

Tamam, ne demek istediğini anladım. Bununla oynadım, fakat alışkanlıkla hala SFINAE'ye çok bağlıydı. Sanırım nihayet tavsiyenizi [bu örnekte] uyguladım (http://cpp.sh/2bsyd) – Matt