【问题标题】:Temporary materialization conversion not in a standard conversion sequence临时实现转换不在标准转换顺序中
【发布时间】:2020-01-05 17:14:33
【问题描述】:

临时实现转换是一种标准转换,请参见第 7.3 节标准转换; 7.3.4[conv.rval]

T 类型的纯右值可以转换为 T 类型的 xvalue。 此转换通过评估以临时对象作为其结果对象的纯右值,从纯右值初始化一个T 类型的临时对象([class.temporary]),并产生一个表示临时对象的xvalue。 T 应该是一个完整的类型。

但是为什么标准转换序列列表中没有提到呢?

[conv]/1:

标准转换序列是按以下顺序的标准转换序列:

  • 从以下集合中进行零次或一次转换:左值到右值的转换、数组到指针的转换和函数到指针的转换。

  • 以下集合中的零个或一个转换:整数提升、浮点提升、整数转换、浮点转换、浮点整数转换、指针转换、指针到成员的转换和布尔转换。

  • 零或一函数指针转换。

  • 零或一次资格转换。

是否因为必须以任何一种方式创建对象,因此不会影响确定转换顺序是否优于另一个?

【问题讨论】:

  • 你能把你的问题自成一体吗?
  • 临时实现不是“转换”操作。那么,如果不是转换,为什么会在“标准转换序列”中呢?
  • 所有问题的相关部分应该是in问题。 不是指向外部网站的链接。
  • @NicolBolas 标准将其称为转换:eel.is/c++draft/conv.rval 实际上在标题standard conversions 下。
  • 我认为你误解了它的意思。转换是从纯右值到极值。这种转换涉及临时实现,但临时实现不是目标。

标签: c++ language-lawyer implicit-conversion


【解决方案1】:

是不是因为一个对象必须以任何一种方式创建,因此不会影响确定转换顺序是否优于另一个?

是的,临时实现不是一种选择,因此它是“免费的”并且不受 ICS 排名的影响。需要时应用,见[expr.basic.lval]/7:

当一个纯右值作为一个操作数的操作数出现时,该操作数需要一个泛左值,temporary materialization conversion 被应用于将表达式转换为一个 xvalue。

例如,dot-expression 要求左侧是泛左值:

struct X {
  void func(int) { }
  void func(long) { }
};

int n = 1;

X().func(n);

这里X() prvalue 必须首先成为一个xvalue(物化),然后我们才能继续.func(n),此时ICS ranking 进入画面来决定如何调用func(n) ,因为可以有不同的转换顺序导致不同的选择。

【讨论】:

  • 我想的更像struct A {}; void f(A); void f(const A&); void g() { f(A()); },因为无论如何都必须进行一些初始化,对于任何这些情况,临时实现转换不需要在转换序列中,因为某种对象会以任何一种方式创建。
  • 整个术语“临时实现”是为 C++17 保证复制省略规则发明的,其中prvalue评估可以延迟。然而,对象迟早会总是物化。它就像 C++ 中的所有内容一样,通过马的后端指定。
  • 所以它不在标准转换序列中,因为无论如何都会发生初始化
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-24
  • 2019-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-14
相关资源
最近更新 更多