我有一个字符串类实现为类模板,如:
template <class T>
class HGStringBasic
{
//...
public:
//...
HGStringBasic& operator += (const T* rhs)
{
//...
}
template <class U, std::enable_if_t<std::is_same<U, char>::value>* = nullptr>
HGStringBasic& operator += (const U* rhs)
{
//...
}
//...
}
代码符合C ++ 11标准。 目标是实现一个重载的运算符+ =(const char),只有在模板的类T是例如&#34; wchar_t&#34;。
时才使用它。我想知道,如果编译器不了解C ++ 11,我将如何获得相同的结果。
更新
我很高兴看到stackoverlow,我还没有看到,我的代码没有完全显示在代码块中。到目前为止,我已经更新了我的代码。
我还修改了模板参数列表中的模板函数运算符+ =()中的错误,TartanLlama你是绝对正确的,is_same<T, char>
必须是is_same<U, char>
。
答案 0 :(得分:1)
enable_if不依赖于C ++ 11的功能。它在boost库中的C ++ 11之前的实现方式几乎与现在实现的方式相同。这是从cppreference.com获得的可能实现:
template<bool B, class T = void>
struct enable_if {};
template<class T>
struct enable_if<true, T> { typedef T type; };
在C ++ 11之前,这在C ++中完全可以正常工作。
答案 1 :(得分:1)
首先,可以在C ++ 2003中轻松实现enable_if / is_same。例如,Boost有它们,或者你可以创造那些你自己的 - 这是一个很好的做法。
其次,如果你不想使用enable_if,你可以简单地为w_char提供myString的特化。为了减少编码量,将它放在一些基类中,从基类派生myString并提供基类的特化。
答案 2 :(得分:0)
首先,您的C ++ 11可以不工作。如果我试着这样做:
myString<int> x;
x += new int(4);
您的operator+=
将无法编译。 SFINAE仅适用于替换的直接上下文 - 但T
不在此处的直接上下文中,只有U
。所以正确的事情是:
template <class U,
class _T=T,
class = std::enable_if_t<std::is_same<_T, char>::value>>
myString& operator += (const U* rhs);
现在回到原来的问题。我们如何在C ++ 03中编写上述内容?同样的想法。我们不能拥有默认模板参数。但同样的原则也适用:我们需要在直接上下文中替换失败:
template <typename T, typename U, typename R>
struct allow_for_char;
template <typename U, typename R>
struct allow_for_char<char, U, R> { typedef R type; };
然后您可以使用它来指定返回类型:
template <class U>
typename allow_for_char<T, U, myString&>::type
operator += (const U* rhs);
答案 3 :(得分:0)
现在我已经弄清楚了,没有c ++ 11和已知的元函数。非常感谢Barry指定返回类型的提示。
这就是我所做的:
#include <type_traits>
template <class _ElemT>
class HGStringBasic
{
public:
// Append char* or wchar_t* depending on specialization
HGStringBasic& operator += (const _ElemT* rhs)
{
return *this;
}
// Allow char* if specialization is wchar_t
template <class U>
typename std::enable_if<std::is_same<U, char>::value, HGStringBasic&>::type operator += (const U* rhs)
{
// Convert ansistring to widestring
return *this;
}
// Allow wchar_t* if specialization is char
template <class U>
typename std::enable_if<std::is_same<U, wchar_t>::value, HGStringBasic&>::type operator += (const U* rhs)
{
// Convert widestring to ansistring
return *this;
}
};