15

在广泛阅读ISO/IEC 14882 编程语言 – C++之后,我仍然不确定为什么const需要使用单个参数构造函数将隐式转换为用户定义的类型,如下所示

#include <iostream>

class X {
public:
   X( int value ) {
      printf("constructor initialized with %i",value);
   }
}

void implicit_conversion_func( const X& value ) {
   //produces "constructor initialized with 99"
}

int main (int argc, char * const argv[]) {
   implicit_conversion_func(99);
}



从第 4 节第 3 行开始

当且仅当声明 T t=e; 时,表达式 e 可以隐式转换为类型 T;对于一些发明的临时变量 t (8.5) 是良构的。某些语言结构要求将表达式转换为布尔值。出现在这种上下文中的表达式 e 被称为在上下文中转换为 bool 并且当且仅当声明 bool t(e); 对于一些发明的临时变量 t (8.5) 是良构的。任一隐式转换的效果与执行声明和初始化然后使用临时变量作为转换的结果相同。如果 T 是左值引用类型 (8.3.2),则结果为左值,否则为右值。当且仅当初始化将表达式 e 用作左值时,表达式 e 才用作左值。

之后,我在 8.5 第 6 行中找到了与用户定义类型相关的初始化程序部分

如果程序要求对 const 限定类型 T 的对象进行默认初始化,则 T 应是具有用户提供的默认构造函数的类类型。

最后,我在 12.3 第 2 行结束了关于用户定义的转换,其中指出

用户定义的转换仅适用于明确的情况(10.2、12.3.2)。

不用说,10.2 和 12.3.2 没有回答我的问题。

  1. 有人可以阐明const对隐式转换有什么影响吗?
  2. 使用const12.3 第 2 行的转换是否“明确”?
  3. 是否会const以某种方式影响第 4 节中讨论的左值与右值?
4

2 回答 2

15

它与隐式转换并没有太大关系。此外,它与转换并没有太大关系。这实际上是关于rvalueslvalues

当您转换99为 typeX时,结果是一个rvalue。在 C++ 中,转换的结果始终是右值(除非您转换为引用类型)。在 C++ 中将非常量引用附加到右值是非法的。

例如,这段代码不会编译

X& r = X(99); // ERROR

因为它试图将非常量引用附加到右值。另一方面,这段代码很好

const X& cr = X(99); // OK

因为将 const 引用附加到右值是完全可以的。

同样的事情也发生在您的代码中。它涉及隐式转换的事实有点无关紧要。您可以用显式转换替换隐式转换

implicit_conversion_func(X(99));

并以同样的情况结束:有const它编译,没有const它不编译。

同样,转换(显式或隐式)在这里扮演的唯一角色是它帮助我们产生一个右值。通常,您可以通过其他方式生成右值并遇到相同的问题

int &ir = 3 + 2; // ERROR
const int &cir = 3 + 2; // OK
于 2010-10-09T04:05:29.097 回答
0

根据第 5.2.2 节第 5 节,当函数的参数是const引用类型时,如果需要,会自动引入临时变量。在您的示例中, 的右值结果X(99)必须放入一个临时变量中,以便该变量可以通过const引用传递给implicit_conversion_func.

于 2010-10-09T04:15:03.450 回答