2016-03-23 19 views
3

ile herhangi bir kurucuyu algılar SFINAE ve variadic şablonlarını kullanarak herhangi bir kurucuyu algılayan bir şablon sınıfı oluşturmaya çalıştım. BununC++, SFINAE

struct MyBadType { 

    MyBadType(int x) { } 

}; 

sonuç: Aşağıdaki türü ile bu test ettiğinizde

template <typename Type, typename ... Arguments> 
struct IsConstructible 
    { 

     template <typename U, decltype(U(Arguments...))* = nullptr> 
     static char test(); 
     template <typename U> 
     static long test(...); 

     static constexpr bool value = sizeof(test<Type>()) == sizeof(char); 

    }; 

Ancak:

IsConstructible<MyBadType, int>::value; 

0. olan yanlış bir şey var mı Burada şablonun kodudur benim şablon denetleyici ile? MSVS 2015 ekspres kullanıyorum.

+0

, "U (Arguments ...)' tarafından "U (std :: declval () ...)' yerine sonra "char" (int) 'ye bir 'int' parametresi ekleyerek başlayın (ardından sizeof (test (0)) ') –

+1

@PiotrSkotnicki Yanıtlar yanıt kutusuna gider. – Barry

cevap

3

Kod derlenmemelidir; MSVC yaparsa uzantıları kullanır. decltype ifadesi mantıklı değil Yani

template <typename U, decltype(U(Arguments...))* = nullptr> 

. U(Arguments...) bir işlev türüdür, ancaktürünü Arguments...'dan oluşturma türünü almak istiyorsunuz. Bunun için std::declval kullanabilirsiniz:

template <typename U, decltype(U(std::declval<Arguments>()...))* = nullptr> 
    static char test(); 
    template <typename U> 
    static long test(...); 

test<type>() bir çağrı belirsiz olacaktır:

template <typename U, decltype(U(std::declval<Arguments>()...))* = nullptr> 

ikinci sorun vardır.

template <typename U, decltype(U(std::declval<Arguments>()...))* = nullptr> 
    static char test(int); 
    //   here ^^^ 
    template <typename U> 
    static long test(...); 

Sonra test<type>(0) gibi işlevini çağırır: belirsizliği çözmek için "klasik" yolu tercih versiyona kukla parametresini vermektir.


Live Demo

aşırı yük belirsizlikleri çözmek amacıyla daha esnek bir yol için this blog post bakınız.

+0

Bu kukla parametre hakkında, (...) aşırı yüklenmemesi her zaman seçim için son mu? Eğer öyleyse, bu nasıl test() aramak için belirsiz? –

+2

@AlexanderBily, bir şeyden elips yüzünden en kötü seçim olarak kabul edilen * bir * dönüşümdür; –

İlgili konular