模板化重载操作符的显式调用

explicit call of templated overloaded operator

本文关键字:调用 操作符 重载      更新时间:2023-10-16

我有一个重载操作符的类。

class sout {
public:
  template<typename T>
  friend inline sout& operator&(sout&, T&);
  friend inline sout& operator&(sout&, std::string&);
};

现在如果我使用模板化操作符&在string .operator&出现错误:

代码:

sout& operator&(sout& s, std::string& str) {
  uint16_t ts = static_cast<uint16_t>(str.size());  // this is ok
  s & ts; // is also ok
  s & static_cast<uint16_t>(str.size());  // but this is wrong
  // ...
  return s;
}
错误:

Error:C2679: binary '&' : no operator found which takes a right-hand operand of type 'uint16_t' (or there is no acceptable conversion)
could be 'sout &operator &<uint16_t>(sout &,T &)'
with
[
    T=uint16_t
]
or       'sout &operator &(sout &,std::string &)'
while trying to match the argument list '(sout, uint16_t)'

,然后尝试使用显式运算符&模板类型:

operator&<uint16_t>(s, ts);  // this also ig ok

但是如果我把它们组合起来,我又会报错:

operator&<uint16_t>(s, static_cast<uint16_t>(str.size())
错误:

'operator &' : cannot convert parameter 2 from 'uint16_t' to 'uint16_t &'

i also try reinterpret_cast.

i know operator&正在期待对uint16_t的引用,而size()函数返回size_t (int)而不是引用。有可能在一行中完成吗?

问题是size()返回的值是一个临时值,临时值是右值;然而,你的函数接受一个左值引用。下面的代码片段澄清了这个问题:

int foo() { return 42; }
void bar(int& i) { i++; } // Parameter is an lvalue reference to non-const
int main()
{
    bar(foo()); // ERROR! Passing an rvalue to bar()
    bar(1729); // ERROR! Passing an rvalue to bar()
    int i = 42;
    bar(i); // OK! Passing an lvalue to bar()
}

左值引用不能绑定到右值,除非它们是对const的引用。

template<typename T>
friend inline sout& operator&(sout&, T const&);
//                                     ^^^^^

如果你的operator&应该修改右手参数,所以引用不能是对const的引用,在c++ 11中你可以使用右值引用(这将允许绑定到左值,以及由于c++ 11的引用崩溃规则):

template<typename T>
friend inline sout& operator&(sout&, T&&);
//                                   ^^^