如何使用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 :(得分:0)
在发布这个问题后不久,我找到了答案。
声明朋友时,我需要使用另一个模板参数来表示CHAR_TYPE
new SimpleLoop(0, i => i <= 12, 1, delegate (int i)
{
try
{
if (i == 5)
{ throw new ArgumentException(); }//raise an other Exception
if (i > 10)
{ SimpleLoop.Break(); }
Console.WriteLine(i);
}
catch (Exception exception)//Catching every Exception, it would be better to catch just ArgumentExceptions
{
if (exception.GetType() == typeof(BreakException))
{ SimpleLoop.Break(); }//Call Break again
Console.WriteLine("Error at " + i);
}
});
编辑:在符合标准的编译器而不是可视化C ++中对此进行测试之后,我发现标准实际上并不允许这样做,并且似乎没有任何方法可以实现它。我已经承认并做了一个帮助班,只是成为了这个。