2016-04-22 102 views
0

我將如何去做一個模板化的運算符與enable_if模板類的朋友?模板類與enable_if模板運算符的朋友

這裏是我的問題的一個例子:

#include <type_traits> 

template<typename CHAR_TYPE> 
class BasicString; 

template<typename CHAR_TYPE, typename OTHER_CHAR_TYPE, 
    typename std::enable_if<((sizeof(CHAR_TYPE)==sizeof(OTHER_CHAR_TYPE)) 
     && std::is_integral<CHAR_TYPE>::value && std::is_integral<OTHER_CHAR_TYPE>::value), std::nullptr_t>::type = nullptr> 
BasicString<CHAR_TYPE> operator+(const BasicString<CHAR_TYPE>& left, const BasicString<OTHER_CHAR_TYPE>& right); 

template<typename CHAR_TYPE, typename OTHER_CHAR_TYPE, 
    typename std::enable_if<((sizeof(CHAR_TYPE)!=sizeof(OTHER_CHAR_TYPE)) 
     && std::is_integral<CHAR_TYPE>::value && std::is_integral<OTHER_CHAR_TYPE>::value), std::nullptr_t>::type = nullptr> 
BasicString<CHAR_TYPE> operator+(const BasicString<CHAR_TYPE>& left, const BasicString<OTHER_CHAR_TYPE>& right); 

template<typename CHAR_TYPE> 
class BasicString 
{ 
private: 
    CHAR_TYPE* characters; 
    size_t length; 

    template<typename OTHER_CHAR_TYPE, 
     typename std::enable_if<((sizeof(CHAR_TYPE)==sizeof(OTHER_CHAR_TYPE)) 
      && std::is_integral<CHAR_TYPE>::value && std::is_integral<OTHER_CHAR_TYPE>::value), std::nullptr_t>::type> 
    friend BasicString<CHAR_TYPE> operator+<CHAR_TYPE, OTHER_CHAR_TYPE>(const BasicString<CHAR_TYPE>& left, const BasicString<OTHER_CHAR_TYPE>& right); 
    template<typename OTHER_CHAR_TYPE, 
     typename std::enable_if<((sizeof(CHAR_TYPE)!=sizeof(OTHER_CHAR_TYPE)) 
      && std::is_integral<CHAR_TYPE>::value && std::is_integral<OTHER_CHAR_TYPE>::value), std::nullptr_t>::type> 
    friend BasicString<CHAR_TYPE> operator+<CHAR_TYPE, OTHER_CHAR_TYPE>(const BasicString<CHAR_TYPE>& left, const BasicString<OTHER_CHAR_TYPE>& right); 

public: 
    BasicString() 
     : length(0), 
     characters((CHAR_TYPE*)std::malloc(sizeof(CHAR_TYPE))) 
    { 
     characters[0] = 0; 
    } 

    BasicString(const BasicString& str) 
     : length(str.length), 
     characters((CHAR_TYPE*)std::malloc(sizeof(CHAR_TYPE)*(str.length+1))) 
    { 
     for(size_t i=0; i<length; i++) 
     { 
      characters[i] = str.characters[i]; 
     } 
    } 

    ~BasicString() 
    { 
     delete characters; 
    } 
}; 

template<typename CHAR_TYPE, typename OTHER_CHAR_TYPE, 
    typename std::enable_if<((sizeof(CHAR_TYPE)==sizeof(OTHER_CHAR_TYPE)) 
     && std::is_integral<CHAR_TYPE>::value && std::is_integral<OTHER_CHAR_TYPE>::value), std::nullptr_t>::type> 
BasicString<CHAR_TYPE> operator+(const BasicString<CHAR_TYPE>& left, const BasicString<OTHER_CHAR_TYPE>& right) 
{ 
    BasicString<CHAR_TYPE> newStr; 
    CHAR_TYPE* characters = newStr.characters; 
    //do some stuff. irrelevant to question 
} 

template<typename CHAR_TYPE, typename OTHER_CHAR_TYPE, 
    typename std::enable_if<((sizeof(CHAR_TYPE)!=sizeof(OTHER_CHAR_TYPE)) 
     && std::is_integral<CHAR_TYPE>::value && std::is_integral<OTHER_CHAR_TYPE>::value), std::nullptr_t>::type> 
BasicString<CHAR_TYPE> operator+(const BasicString<CHAR_TYPE>& left, const BasicString<OTHER_CHAR_TYPE>& right) 
{ 
    BasicString<CHAR_TYPE> newStr; 
    CHAR_TYPE* characters = newStr.characters; 
    //do some stuff. irrelevant to question 
} 

int main() 
{ 
    BasicString<char> str1; 
    BasicString<wchar_t> str2; 
    BasicString<char> newStr = str1 + str2; 
    return 0; 
} 

我知道,我可以使用的輔助函數或輔助類,但我寧願沒有,如果我能避免它。

當我編譯這個時,我得到的錯誤,運算符函數不能訪問該類的私有成員,這意味着我的結婚代碼不起作用。我將如何去結交這些功能?

回答

0

所以在發佈這個問題後不久,我想出了答案。

聲明朋友的時候,我需要使用另一個模板參數來表示CHAR_TYPE

template<typename _CHAR_TYPE=CHAR_TYPE, typename OTHER_CHAR_TYPE, 
     typename std::enable_if<((sizeof(_CHAR_TYPE)==sizeof(OTHER_CHAR_TYPE)) 
      && std::is_integral<_CHAR_TYPE>::value && std::is_integral<OTHER_CHAR_TYPE>::value), std::nullptr_t>::type> 
friend BasicString<_CHAR_TYPE> operator+<_CHAR_TYPE, OTHER_CHAR_TYPE>(const BasicString<_CHAR_TYPE>& left, const BasicString<OTHER_CHAR_TYPE>& right); 

    template<typename _CHAR_TYPE=CHAR_TYPE, typename OTHER_CHAR_TYPE, 
     typename std::enable_if<((sizeof(_CHAR_TYPE)!=sizeof(OTHER_CHAR_TYPE)) 
      && std::is_integral<_CHAR_TYPE>::value && std::is_integral<OTHER_CHAR_TYPE>::value), std::nullptr_t>::type> 
friend BasicString<_CHAR_TYPE> operator+<_CHAR_TYPE, OTHER_CHAR_TYPE>(const BasicString<_CHAR_TYPE>& left, const BasicString<OTHER_CHAR_TYPE>& right); 

編輯:在標準測試此標準的編譯器,而不是VISUAL C++之後,我發現,該標準實際上沒有按」不允許這樣做,而且似乎沒有任何實際實現它的方法。我已經承認並且成爲了一個幫手類,並且只是結識了他。