編譯器錯誤的原因是if
語句的兩個分支都將用模板實例化。這顯然是一個錯誤,因爲如果T = int
沒有賦值運算符std::string
。 C++ 17引入了無視在編譯時的一個分支的方法,叫做if constexpr
:
template <class T> void MyClass::set(T value) {
if constexpr (std::is_same<T, std::string>::value) {
stringValue_ = value;
} else if (std::is_same<T, int>::value) {
intValue_ = value;
}
}
但實際上,這裏不使用模板(這裏要麼不使用SFINAE !)。只需使用舊的功能重載。
class MyClass
{
std::string stringValue_;
int intValue_;
public:
void set(int);
void set(std::string);
};
void MyClass::set(int value) {
intValue_ = value;
}
void MyClass::set(std::string value) {
stringValue_ = value;
}
有人可能會說SFINAE實際上是必要的,如果你想覆蓋的可被轉換爲對方類型的整個範圍。
class MyClass
{
std::string stringValue_;
int intValue_;
public:
template < typename T, typename std::enable_if< std::is_arithmetic<T>::value, void** >::type = nullptr >
void set(T value) {
intValue_ = value;
}
template < typename T, typename std::enable_if< std::is_same<T,std::string>::value, void** >::type = nullptr >
void set(T value) {
stringValue_ = value;
}
};
您可以使用['std :: enable_if'](http://en.cppreference)創建兩個不同的'MyClass :: set'函數。com/w/cpp/types/enable_if)根據你的'std :: is_same'條件選擇正確的一個 – CoryKramer
那麼我在這裏試圖做的是無效的?我正在這樣做,以消除代碼。你的解決方案確實會起作用,但會打敗這個目的。 – user1765354
@ user1765354爲什麼'MyClass :: set'需要成爲一個模板,如果唯一的參數將是'int's和'std :: string's?爲什麼不只有兩個非模板重載?它幾乎沒有任何額外的代碼。 – Brian