2

我有一个字符串类实现为类模板,如:

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 是例如“wchar_t”时使用。

我想知道,如果编译器不理解 C++11,我如何能达到相同的结果。

更新: 对不起,我是 stackoverlow 的新手,我还没有看到,我的代码没有完全显示在代码块中。到目前为止,我已经更新了我的代码。我还从模板函数运算符 += () 中纠正了模板参数列表中的一个错误,TartanLlama 你绝对正确,is_same<T, char>必须是is_same<U, char>.

4

4 回答 4

1

enable_if 不依赖于 C++11 功能。它在 C++11 之前在 boost 库中的实现方式几乎与现在的实现方式相同。这是取自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++ 中可以正常工作。

于 2015-10-16T14:53:35.500 回答
1

首先,enable_if/is_same 可以很容易地在 C++2003 中实现。例如,Boost 拥有它们,或者您可以自己创建它们 - 这是一个很好的做法。

其次,如果您不想使用 enable_if,您可以简单地为 w_char 提供 myString 的特化。为了减少编码量,将其放在某个基类中,从基类派生 myString 并提供基类的专门化。

于 2015-10-16T14:55:03.693 回答
1

现在我已经弄清楚了,没有 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;
        }
};
于 2015-10-21T08:21:19.920 回答
1

首先,您的 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);
于 2015-10-16T16:14:54.423 回答