2016-10-05 120 views
0

我見過很多關於方法上下文中專業化的問題,但沒有看到屬於類的函數。我很難將這些問題所傳遞的知識轉化爲我的問題。模板類方法的特化。 「功能模板已經定義」

我在用我過去創建的類學習,我想爲算術類型進行專門化。

template <typename T> 
class Vector3 
{ 
public: 
    T x; 
    T y; 
    T z; 

public: 
    operator std::string() const; 
} 

這是我想要做的專業化:

template<typename T = std::enable_if<std::is_arithmetic<T>::value, T>::type> 
inline Vector3<T>::operator std::string() const { 

    std::stringstream ss; 
    ss << "NOT NUMBER {" << x << ", " << y << ", " << z << "}"; 

    return ss.str(); 
} 

template<typename T = std::enable_if<!std::is_arithmetic<T>::value, T>::type> 
inline Vector3<T>::operator std::string() const { 

    std::stringstream ss; 
    ss << "NUMBER {" << x << ", " << y << ", " << z << "}"; 

    return ss.str(); 
} 

然而,當我嘗試編譯,我得到

錯誤C2995:「的Vector3 ::運算符的std ::字符串(void)const':功能 模板已被定義

當我谷歌這一點時,通常情況下,人們已經在CPP文件以及頭文件中定義了他們的類/方法。由於我只在頭文件中執行此操作,因此我只能假設enable_if不正確。當我看其他例子時,他們只是專門研究,但我想用is_arithmitic的方式。

我在做什麼錯?在此先感謝

回答

4

默認位置:

template<typename T = XXX> 
inline Vector3<T>::operator std::string() const { ... } 

不會在所有問題,有沒有扣在這一點上怎麼回事,已經被定義T。這是合法的,但它只是噪音。

現在,你不能部分專注於某一類模板的成員函數要麼,但我們可以對性狀調度:

template <class T> 
class Vector3 { 
public: 
    // ... 
    operator std::string() const { 
     return as_string(std::is_arithmetic<T>{}); 
    } 

private: 
    std::string as_string(std::true_type) { 
     // implementation for arithmetic types 
    } 

    std::string as_string(std::false_type) { 
     // implementation for non-arithmetic types 
    } 
}; 
+0

感謝您的回覆。在所有的搜索結果中,我都有一種感覺,我不得不使用標籤分發...我會看看有沒有人有任何其他想法,然後將其標爲正確。 – user819640

1

巴里的答案是完美的。

下面是一些解釋和建議:

http://en.cppreference.com/w/cpp/types/enable_if

「一個常見的錯誤是聲明的區別僅在於它們的默認模板參數二元函數模板,這是非法的,因爲默認模板參數不是的一部分函數模板的簽名,並且使用相同的簽名聲明兩個不同的函數模板是非法的。「