2

假设我们在库中定义了全局运算符(全部在全局命名空间中)

template< class tAnyType >
SpecialStream & operator << ( SpecialStream & os, tAnyType && value )
{
    return os.serialize( std::forward<tAnyType>( value ) );
}

我想为我的一门课重载/专业化(是哪一个?),例如:

SpecialStream & operator << ( SpecialStream & os, const MyClass & value )
{
    return os << value.i << value.s.c_str();
}

我想要一个运算符重载,它可以与 const/non-const 左值和右值一起使用,就像库中的那个一样。

事实证明,我必须至少制作三个:

  • "MyClass &" 捕获非常量左值
  • "const MyClass &" 捕获 const 左值
  • "MyClass &&" 捕获右值

必须为每个专业类编写三个重载似乎并不正确。我不应该能够使用“const MyClass &”(正如我们在“流”类重载<<中随处可见)或使用“MyClass &&”(应该能够捕获所有内容)捕获所有内容吗?

这是使用带有“const MyClass &”的单个运算符的尝试(不编译),对于任何类型的参数都应该没问题:

#include <iostream>

using namespace std;
//---------------------------------------
// Radically simplified code from a library, in global namespace 

class SpecialStream
{
public:
    template< class tAnyType >
    SpecialStream & serialize( tAnyType && value )
    {
        cout << value;  // whatever, just an example         <-- line 13
        return *this;
    }
};

// global operator that I’d like to overload/specialize for a specific class
template< class tAnyType >
SpecialStream & operator << ( SpecialStream & os, tAnyType && value )
{
    return os.serialize( forward<tAnyType>( value ) );    // <-- line 22
}
//---------------------------------------

//---------------------------------------
// code from my project 
class MyClass
{
public:
    int i;
    string s;
};

// Global operator overload/specialization (does not work! See question below)
// Tried const MyClass &, Myclass &&, MyClass
SpecialStream & operator << ( SpecialStream & os, const MyClass & value )
{
    return os << value.i << value.s.c_str();
}

int main( int argc, char ** argv )
{
    SpecialStream oss;
    MyClass     object;
    oss << object;          // compiler error!             <-- line 46
}

上面没有编译,因为在 oss << 对象上,编译器总是尝试使用库中的模板运算符,而不是我的。我正在使用 Visual Studio 2015(更新 3),我认为这对于 C++11 的这一部分是可以的。编译器错误是:

1>test.cpp(13): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'MyClass' (or there is no acceptable conversion)

接下来是编译器尝试过的所有二元运算符 << 的很长列表,例如:

note: could be 'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(std::basic_streambuf<char,std::char_traits<char>> *)'
note: or       'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(const void *)'

然后最后(我们看到问题是它试图实例化第 22 行而不是使用我的运算符):

1>  test.cpp(13): note: while trying to match the argument list '(std::ostream, MyClass)'
1>  test.cpp(22): note: see reference to function template instantiation 'SpecialStream &SpecialStream::serialize<MyClass&>(tAnyType)' being compiled
1>          with
1>          [
1>              tAnyType=MyClass &
1>          ]
1>  test.cpp(46): note: see reference to function template instantiation 'SpecialStream &operator <<<MyClass&>(SpecialStream &,tAnyType)' being compiled
1>          with
1>          [
1>              tAnyType=MyClass &
1>          ]

库代码的设计是好是坏可能是一个问题,但这不是我现在要问的。正如我所说,复制我的运算符以获取(非常量) MyClass & 工作正常,但我很确定我不应该复制代码(SpecialStream 毕竟使用单个运算符完成所有操作)。

有没有办法在一个函数中做到这一点?

4

0 回答 0