【问题标题】:explicit call of templated overloaded operator显式调用模板化重载运算符
【发布时间】:2013-04-25 15:52:46
【问题描述】:

我有一个带有重叠运算符的类。

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

  friend inline sout& operator&(sout&, std::string&);
};

现在,如果我在 sting.operator& 中使用模板化的 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 &'

我也尝试过 reinterpret_cast。

我知道 operator& 期望引用 uint16_t 并且 size() 函数返回 size_t (int) 而不是引用。是否可以在一行中做到这一点?

【问题讨论】:

  • 也许使用 const 引用

标签: c++ templates casting operator-overloading


【解决方案1】:

问题是size()返回的值是临时的,而临时的都是右值;但是,您的函数接受 lvalue 引用。下面的 sn -p 说明了这个问题:

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&amp; 应该修改右手参数,这样引用就不能是对 const 的引用,在 C++11 中你可以使用右值引用(这也将允许绑定到左值由于 C++11 的引用折叠规则):

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

【讨论】:

  • @itwasntpete:别担心,会发生的 ;)
猜你喜欢
  • 2020-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-03
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
相关资源
最近更新 更多