首页 文章

模板类的模板操作员朋友,带有enable_if

提问于
浏览
0

我如何使用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;
}

我知道我可以使用辅助函数或辅助类,但如果我能避免它,我宁愿不这样做 .

当我编译它时,我得到运算符函数无法访问类的私有成员的错误,这意味着我的友好代码不起作用 . 我将如何与这些功能交朋友?

1 回答

  • 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);
    

    编辑:在符合标准的编译器而不是视觉C中测试之后,我发现标准实际上不允许这样做,并且似乎没有任何方法可以实现它 . 我已经承认并做了一个帮助班,并且只是成为了朋友 .

相关问题