2016-04-22 12 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); 

EDIT表現するために、別のテンプレートパラメータを使用する必要があります。標準で代わりのVisual C++の対応のコンパイラを、これをテストした後、私は「標準が実際にdoesnのことがわかってきましたがこれを許し、実際にそれを達成する方法はないようです。私は認めて、ヘルパークラスを作って、ちょうどそれに気づいた。

関連する問題