2015-04-07 17 views
13

Uygun enable_if kullanımı ve şablon uzmanlığı konusunda bir sorunla karşılaşıyorum.Şablon uzmanlığı ve enable_if sorunları

#include <type_traits> 
#include <iostream> 

template <class T, 
      class = typename std::enable_if<std::is_floating_point<T>::value>::type> 
    bool less(T a, T b) { 
    // .... 
} 

template <class T, 
      class = typename std::enable_if<std::is_integral<T>::value>::type> 
    bool less(T a, T b) { 
    // .... 
} 

int main() { 
    float a; 
    float b; 
    less(a,b); 
    return 0; 
} 

Yukarıdaki kod derleme değil -

I have function called "less" that checks if 1st arg is less than 2nd arg. Let's say I want to have 2 different kinds of implementations depending on the type of input - 1 implementation for integer and another for double.

Ben şimdiye kadar bu gibi görünüyor var kodu:

(gizlilik nedenleriyle) örnek değiştirdikten sonra, burada bir karşılaştırılabilir örnek çünkü - Daha az yöntemi yeniden tanımladığımı söylüyor.

Hatalar şunlardır:

Z.cpp:15:19: error: template parameter redefines default argument 
      class = typename std::enable_if<std::is_integral<T>::value>::type> 

       ^
Z.cpp:9:19: note: previous default template argument defined here 
      class = typename std::enable_if<std::is_floating_point<T>::value>::type> 
       ^

Z.cpp:16:11: error: redefinition of 'less' 
    bool less(T a, T b) { 
     ^

Z.cpp:10:11: note: previous definition is here 
    bool less(T a, T b) { 
     ^

Z.cpp:23:5: error: no matching function for call to 'less' 
    less(a,b); 
    ^~~~ 

Z.cpp:15:43: note: candidate template ignored: disabled by 'enable_if' 
     [with T = float] 
      class = typename std::enable_if<std::is_integral<T>::value>::type> 
             ^
3 errors generated. 

birisi hata burada neler olduğunu işaret edebilir?

+0

temel olarak, dönüş türünü nasıl çağırdığınızdan dolayı 'enable_if' kullanmıyorsunuz. – Alex

+0

Hızlı çözüm, şablonlardan birine ayrı bir aşırı yük olarak değerlendirilebilmesi için bir elips parametresi '...' eklemektir. – 0x499602D2

+1

Veya imzayı "template :: value> :: type * = nullptr> ' – vsoftco

cevap

18

Varsayılan şablon argümanları, bir işlev şablonunun imzasının bir parçası değildir. Örneğinizde, yasadışı olan less'un iki aynı aşırı yüklenmesine sahipsiniz.

error: redefinition of ' template<class T, class> bool less(T, T) '

düzeltmek için Hata taşıyın enable_if ekspresyonu: çınlama gcc aşağıdaki hata iletisini oluşturur ise, (§14.1/12 [temp.param] 'e göre, aynı zamanda kaçak olan) varsayılan argüman yeniden tanımlanması şikayet varsayılan argüman gelen bir kukla şablon parametresine

template <class T, 
      typename std::enable_if<std::is_floating_point<T>::value, int>::type* = nullptr> 
    bool less(T a, T b) { 
    // .... 
} 

template <class T, 
      typename std::enable_if<std::is_integral<T>::value, int>::type* = nullptr> 
    bool less(T a, T b) { 
    // .... 
} 

Diğer bir seçenek Bunu okumak zordur hissetmek olsa dönüş türü enable_if kullanmaktır.

template <class T> 
     typename std::enable_if<std::is_floating_point<T>::value, bool>::type 
     less(T a, T b) { 
    // .... 
} 

template <class T> 
    typename std::enable_if<std::is_integral<T>::value, bool>::type 
    less(T a, T b) { 
    // .... 
} 
+0

Teknik olarak, ilk kod kümesi bozuk biçimlidir standarda göre, çünkü void * 'şablon olmayan bir parametre için geçerli bir tip değildir. Pratikte, bildiğim bir derleyici aslında umurunda değil. Düzeltme olsa da, önemsizdir. –

+0

@ T.C. TIL ... – Praetorian

+0

'u işaretlediğiniz için teşekkürler. Bir işlev parametresi olarak değiştirdim ve şimdi çalışıyor – user855

İlgili konular