c++ - 关于 C++ 标准的歧义
问题描述
根据此代码:
#include <iostream>
using namespace std;
struct T {
T() { cout << "default"<<endl; }
T(string s) { cout << "ctor "<< endl; }
T(const T& t) { cout << "copy ctor"<< endl; }
};
int main()
{
T x = T(T(T()));
return 0;
}
输出 :
default
并根据标准:
(17) 初始化器的语义如下。目标类型是正在初始化的对象或引用的类型,源类型是初始化表达式的类型。如果初始化器不是单个(可能是带括号的)表达式,则未定义源类型。
......
(17.6.1) 如果初始化表达式是纯右值并且源类型的 cv 非限定版本与目标类是同一类,则初始化表达式用于初始化目标对象。[例子:T x = T(T(T())); 调用 T 默认构造函数来初始化 x。——结束示例]
它在 c ++ 11 (GNU GCC v7.1.1) 中给出了相同的结果
第一个问题:此语句中是否定义了源类型?
T x = T(T(T()));
现在,如果我们将此函数添加到此代码中:
string f(T t) {return "str";}
并替换T x = T(T(f(T())));
为T x = T(T(T()));
输出 :
default
ctor
现在定义了源类型吗?
不是T()
初始化表达式吗?
如果是,按照标准,应该调用默认构造函数,但是为什么要T(string s)
为x调用呢?
解决方案
此语句中是否定义了源类型?
T x = T(T(T()));
是的,因为T(T(T()))
是单个表达式;在这种情况下,它可以被paranthesized。
同样的道理适用于
T(T(f(T())))
因为这也是一个表达式。
不是 T() 初始化表达式吗?
一般来说,当然,但不是在上述情况下。=
和之间的整个表达式;
是初始化表达式。
但是为什么要为 x 调用 T(string s)?
因为有一个显式调用f
返回 a string
,并且该参数用于构造 a T
,它调用string
构造函数。
T x = T( T(f( T() )) );
// ^^^ calls the default constructor
// ^^^^^^^^^^^^^ calls the string constructor
推荐阅读
- python - stripe:如何将条带模型对象转换为 JSON 以获得完整的分层数据?
- python-3.x - 带有签名的芹菜和弦KeyError
- html - 具有只读输入我无法复制值
- asp.net - WebApi 返回序列化的 HttpResponseMessage 而不是 text/html
- python-3.x - 在python的'for'循环中计算NaN
- wordpress - WooCommerce - 不要授权或捕获新订单
- c# - 如何使用多线程或 c# 中的任何其他机制在 Windows 服务中同时处理多个请求?
- batch-file - 批处理脚本 - 如何获取一年中每个星期一的日期
- javascript - 使用 Nashorn 在 Java 中运行带有导出功能的 Javascript 代码
- ios - 崩溃:AVAudioSession 通知线程 EXC_BAD_ACCESS