2015-09-27 40 views
1

我想寫條件只有數字的模板。C++ 11模板條件

//in header file 
template <typename T, 
    typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type 
> 
class Foo 
{ 
    public: 
     Foo(); 
}; 

#include "Foo.inline" 

而且

//In inline file 
template < 
    typename T 
> 
Foo<T>::Foo() 
{ 
}; 

然而,這並不編譯。應該如何在單獨的文件中實現模板的語法?

+0

@MarcoA。我知道,但我不知道該寫什麼,因爲tempalte中的第二個paarmetr是無名的 –

回答

1

與您的代碼的問題是,你違約了第二個模板參數T如果第一個滿足is_arithmetic。這將工作的情況下,1而不是2的情況下

template <typename T, 
      typename U = typename std::enable_if<std::is_arithmetic<T>::value, T>::type> 
class Foo { 
    public: 
     Foo(); 
}; 

template <typename T, typename U> 
Foo<T, U>::Foo() { 
} 

struct Obj {}; 

int main() { 
    Foo<int> obj; // Fine 
    // Foo<Obj> obj2 // 1) Error - as it should be 
    Foo<std::string, Obj> obj3; // 2) Works fine - bad 
} 

Live Example

爲了避免實例,如果第一類是無效的is_arithmetic你應該使用一個static_assert

template <typename T> 
class Foo { 
    static_assert(std::is_arithmetic<T>::value, "T is not an arithmetic type"); 
    public: 
     Foo(); 
}; 

template <typename T> 
Foo<T>::Foo() { 
} 

Live Example

+0

謝謝你的例子和解釋 –

1

應該在定義中使用第二個模板參數。

//in header file 
template <typename T, 
    typename Enable = typename std::enable_if<std::is_arithmetic<T>::value, T>::type 
> 
class Foo 
{ 
    public: 
     Foo(); 
}; 


//In inline file 
template <typename T, typename Enable> 
Foo<T, Enable>::Foo() 
{ 
}; 
+0

但是用這個,我可以寫Foo foo;和代碼編譯 –

+1

Foo類有兩個模板參數。即使第二個參數未命名,也沒有任何東西可以阻止你寫'Foo '。 您可以使用類型別名隱藏第二個參數。 –

3

std::enable_if是用於觸發替代故障是有用的,以便編譯器可以回退到另一個過載/專業化。

如果您想驗證一個模板參數,把適當的條件在static_assert

template <typename T> 
class Foo 
{ 
    static_assert(std::is_arithmetic<T>::value, 
        "T must be an arithmetic type"); 
public: 
    Foo(); 
}; 

template <typename T> 
Foo<T>::Foo() 
{ 
}