2015-05-25 16 views
14

Bu kesinlikle önemsiz bir sorudur, ancak nasıl yapılacağını anlayamadım.Şablon parametresi ayrımına bağlı olarak farklı işlevler yürütme

Şablon işlevim var, template <unsigned int N> void my_function() deyin. Şimdi, my_function için iki farklı uygulama var, ilk N, 100, diğerinden daha büyükse N bundan daha küçükse, kullanılmalıdır.

template <unsigned int N, typename = enable_if <N >= 100> :: type> my_function() 
{ 
    // First implementation 
} 

template <unsigned int N, typename = enable_if <N < 100> :: type> my_function() 
{ 
    // Second implementation 
} 

Ama bu aynı fonksiyonu iki kere ilan ediyor:

böyle SFINAE kullanmaya çalıştı. Sonra

template <unsigned int N, bool = (N >= 100)> my_function(); 

böyle bir şey yaptığını Ve sonra boole iki farklı değerlere sahip iki işlevi uygulayan çalıştı. Başarı yok, çünkü kısmi bir uzmanlık.

Sonra, struct parametresi olarak N sarmayı denedim ve işlev çağrısı içinde boole, ancak sınıfın özelleştirilmesinden önce bir üye işlevi uzmanlaşıyor, bu da yapılamıyor.

Bunu yapmanın makul bir yolu var mı?

cevap

12

yerine bu deneyin:

#include <type_traits> 
#include <iostream> 

template <unsigned int N, typename std::enable_if <N >= 100> :: type* = nullptr> 
void my_function() 
{ 
    std::cout << "N >= 100" << std::endl; 
} 

template <unsigned int N, typename std::enable_if <N < 100> :: type* = nullptr> 
void my_function() 
{ 
    std::cout << "N < 100" << std::endl; 
} 

int main() 
{ 
    my_function<42>(); 
    my_function<100>(); 
} 

Template default parameters do not participate in the overload (ve dolayısıyla SFINAE geçerli değildir). SFINAE devreye giriyor böylece Öte yandan, yukarıda snippet'te bağımlı şablon olmayan tip parametresi, atamanın sol tarafındadır

2

Sen dönüş türüne SFINAE kullanabilir.

template <unsigned int N> 
enable_if_t<(N >= 100)> my_function() 
{ 
    // First implementation 
} 

template <unsigned int N> 
enable_if_t<(N < 100)> my_function() 
{ 
    // Second implementation 
} 

, T için farklı varsayılan tür yalnızca template <unsigned int N, typename T> var. Kısmi uzmanlaşma için

, sen yapısına ileri olabilir: Eğer herhangi bir nedenle enable_if beğenmezseniz, her zaman etiket sevk gidebilir,

template <unsigned int N, bool = (N >= 100)> 
struct my_function_impl; 

template <unsigned int N> 
struct my_function_impl<N, true> 
{ 
    void operator() const { /* First implementation */} 
}; 

template <unsigned int N> 
struct my_function_impl<N, false> 
{ 
    void operator() const { /* Second implementation */} 
}; 

template <unsigned int N> 
void my_function() { my_function_impl<N>{}(); } 
5

:

#include <type_traits> 
class low {}; 
class high {}; 
template <int N, class T> 
    void func(T, low) 
    { 
     // version for high N 
    } 
template <int N, class T> 
    void func(T, high) 
    { 
     // version for low N 
    } 
template <int N, class T> 
    void func(T val) 
    { 
     func<N>(val, std::conditional_t<(N>=100), high, low>{}); 
    } 
int main() 
{ 
    func<3>(3.14159); // low version 
    func<256>("Yo"); // high version 
} 

Bu ise Bu durumda, etiketleri true_type ve false_type gibi basit şeylerle sınırlayabiliriz, ancak genel olarak bu alternatif bir yaklaşım olabilir.

+0

Bunu beğendim! Bir dahaki sefere kullanacağım, teşekkürler! –

İlgili konular