【问题标题】:Was it intentional that the conversion operator template<typename T> T&&() is a conversion to an rvalue?转换运算符 template<typename T> T&&() 是否有意转换为右值?
【发布时间】:2019-09-20 23:17:44
【问题描述】:

我正在编写一个转换运算符,用于将类转换为左值或右值。所以我假设:

struct C
{
    int x;

    template<typename T>
    operator T&&() {
      return std::forward<T>(x);
    }
};

int main() {
  C x;
  int&& rv_i  = std::move(x);
  int   rv_i2 = x;
  //int&  rv_i3 = x; // fails
}

会同时添加两者。我很惊讶它只添加了一个转换运算符,该运算符转换为T 类型的右值。这是标准故意的还是 g++、clang++ 和 VC++ 中的错误?

因此,它再次需要复制更多功能。 :(

【问题讨论】:

  • FWIW,std::move 总是会给你一个右值,std::forward 会有条件地给你一个。你有没有这些还不够的用例?
  • 甚至无法编译。
  • 将运算符转换为 ref 不是直接上下文,因此很遗憾它不是转发引用。该区域在标准中也不清楚。 I've been bitten by that recently.
  • @Swordfish,对不起。错字。为更完整的示例添加了附加代码。
  • @GuillaumeRacicot,您所说的“不在直接上下文中”是什么意思?

标签: c++ c++11 language-lawyer


【解决方案1】:

我认为你问错了问题。

首先让我们介绍一下价值类别的角度。如果它返回T&amp;,则调用运算符的结果是一个左值,如果它返回T,它是一个prvalue,如果它返回T&amp;&amp; (ref),它是一个xvalue。

您真正想知道的是您的运算符返回什么类型,考虑到使用看起来像通用引用的东西。但是,它不是通用参考。 T&amp;&amp; 类型的函数参数将是一个通用引用,但这不会使 T&amp;&amp; 类型成为某种神奇的变色龙。在这里,您将返回一个 rvalue-ref-to-T,句点。根据上述,这会产生一个 xvalue(一种右值)。

既然我们知道运营商正在做它应该做的事情,那么我们怎样才能以不同的方式做事呢?这实际上取决于您要完成的工作,这没有完全说明。但您可能正在寻找std::movestd::forward

【讨论】:

  • 更新了问题的例子。
  • 是的,我很快发现它不是一个通用参考。但是,由于它像参数一样处于类型推导上下文中,因此将其视为这样是有道理的。
  • @Adrian “像参数一样在类型推导上下文中” 是吗?
  • 怎么不是@LightnessRacesinOrbit?必须推导出它要转换为的类型。当我说int&amp;&amp; rv_i = std::move(x); 时,编译器必须推断出我正在尝试将x 转换为int&amp;&amp;
  • 如果不喜欢参数,则以类似的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-13
  • 1970-01-01
  • 2018-08-18
  • 2012-01-31
  • 1970-01-01
  • 2018-10-27
相关资源
最近更新 更多