2012-04-04 23 views
5

yaparakİhtisas şablon

template <int n> 
void f(){...}; 

ben n belirli değerleri için bunu uzmanlaşmak biliyorum bir şablon Verilen:

template <> 
void f<2>(){...}; 

Ama beni sağlayan bir yöntem yoktur Tüm pozitif n için uzmanlaşmak için?

aşağıdaki

template <int n> 
void f<n>(){ 
    int dummy[n]; //invalid for n < 0 
    ... 
}; 

yapmayı düşündünüz Yani n<0 için bu kodu geçersiz ve derleyici önceki tanımına başvuracaktır. Ne yazık ki, tüm aldığım redefinition of 'void f<n>()' hatasıdır.

Not: Sanırım bu muhtemelen standart tarafından desteklenmiyor. Bu efekti elde etmek için bir yöntem (belki de bazı şablon metaprogramlama) olup olmadığını soruyorum.

cevap

13

Bir seçenek, başka bir düzeyde bir indirgeme kullanmaktır. n numarası ve n'un negatif olup olmadığını temsil eden n numaralı ve bool numaralı sayıyı içeren bağımsız bir şablon tanımlayın, ardından o şablonun n ne zaman negatif olduğunu belirleyin. Ardından, f işlevinizin şablonu doğru argümanlarla başlatmasını sağlayın. Örneğin

:

template <int n, bool isNegative> struct fImpl { 
    static void f() { 
     /* ... code for when n is positive ... */ 
    } 
}; 
template <int n> struct fImpl<n, true> { 
    static void f() { 
     /* ... code for when n is negative ... */ 
    } 
}; 

template <int n> void f() { 
    fImpl<n, (n < 0)>::f(); 
} 

Diğer bir seçenek SFINAE overloading ve C++, 11 (ya da Boost eşdeğeri) std::enable_if şablon sınıfı kullanmaktır; Doğru sürümü daima adı verilecek, böylece n, doğru işareti varsa

template <int n> void f(typename std::enable_if<(n < 0)>::type* = 0) { 
    /* ... n is negative ... */ 
} 

template <int n> void f(typename std::enable_if<(n >= 0)>::type* = 0) { 
    /* ... n is positive ... */ 
} 

bu fonksiyonların her biri

sadece aşırı yük çözünürlük için hazır olacaktır.

Bu yardımcı olur umarız!

+5

Stil konusu, ancak 'enable_if'i dönüş türüne koymayı tercih ediyorum, bu nedenle kafa karıştırıcı şeyler (kullanıcıların ve işlevlerin türü) etrafında asılı bir sihirli parametre yoktur. – GManNickG