为什么它不能重载“operator<<”在std :: string上?

时间:2016-07-24 02:42:33

标签: c++ templates c++11 operator-overloading overloading

#include <string>
#include <type_traits>

using namespace std;

template
<
    typename CharT,
    template<typename> class Traits,
    template<typename> class Allocator,
    typename RightT,
    typename StringT = basic_string
    <
    CharT,
    Traits<CharT>,
    Allocator<CharT>
    >
>
enable_if_t
<
    is_constructible<StringT, RightT>::value,
    StringT&
>
operator <<(StringT& lhs, const RightT& rhs)
{
    return lhs.append(rhs);
}

int main()
{
    string s1, s2;
    s1 << s2; // compilation error!

    return 0;
}

我的编译器是VS 2015 Update 3.编译错误消息是:

  

错误:二进制表达式的操作数无效('string'(又名)   'basic_string,allocator&gt;')和   '字符串')

为什么它不能按预期工作?

1 个答案:

答案 0 :(得分:4)

编译器是否为您提供了比该单行更多的信息?类似的东西:

26:1: note: template argument deduction/substitution failed:
35:11: note: couldn't deduce template parameter 'CharT'

如果您更换

operator <<(StringT & lhs, const RightT& rhs)

operator <<(basic_string<CharT, Traits<CharT>, Allocator<CharT>>& lhs, const RightT& rhs)

它编译。<​​/ p>

基本上你是把马放在马前。您可以使用模板参数来形成默认模板arg(StringT = ...,如果您已经知道模板args。您无法使用默认值来确定参数。

如果您想同时支持basic_string和其他/自定义字符串,您可能需要编写两个专业或类似内容。

或者意识到你的模板要求到底是什么 - 你不需要Constructible,你需要&#34;可附加&#34;,所以SFINAE就这样,并忽略它是basic_string还是MyCustomString - 它没有&# 39;重要;唯一重要的是lhs.append(rhs)是否有效(并且,呃,也许可以找出它的返回类型......)