C++ 允许隐式调用显式复制构造函数吗?
考虑以下代码:C++ 允许隐式调用显式复制构造函数吗?,c++,gcc,compiler-bug,C++,Gcc,Compiler Bug,考虑以下代码: #include <cstdio> struct A { A(){} explicit A(const A&) {std::puts("copy");} }; int main() { A a; true ? a : A(); return 0; } #包括 结构A { A(){} 显式A(常数A&){std::put(“copy”);} }; int main() { A A; 是吗?a:a(); 返回0; }
#include <cstdio>
struct A
{
A(){}
explicit A(const A&) {std::puts("copy");}
};
int main()
{
A a;
true ? a : A();
return 0;
}
#包括
结构A
{
A(){}
显式A(常数A&){std::put(“copy”);}
};
int main()
{
A A;
是吗?a:a();
返回0;
}
据我所知,三元函数将尝试复制a,并且应该失败,因为复制构造函数是显式的,但是gcc编译得很好,并创建了一个副本。叮当声像预期的那样吐出一个错误
这是gcc中的错误吗
我在c++17模式下使用gcc 8.1和clang 7.0,但我也在c++98模式下尝试了gcc的所有版本,它们的行为都是一样的。clang拒绝它是正确的,它确实是一个gcc错误。为了简单起见,我将引用n4659(最接近C++17标准的文档) 首先,您的示例中的条件表达式的类型(由指定)必须是
a
类型的prvalue
现在,根据我的观点:
左值到右值、数组到指针、函数到指针标准
对第二个和第三个操作数执行转换
a
必须能够进行左值到右值的转换。对于a
,在(同样强调我的)中指定为
否则,如果T具有类类型,则转换复制将初始化
从glvalue生成结果对象
从A
复制A
的初始化,在任何上下文中,都应该在重载解析()中选择一个转换构造函数:
T的转换构造函数是候选函数
并且显式复制构造函数不是转换构造函数()
非显式的复制/移动构造函数([class.copy])是一个转换构造函数
一个一致的C++实现,不能接受你所写的条件表达式。
是一个带有该代码的GooBoad链接。(你可以通过点击“共享”按钮得到一个。)Clang拒绝它,而gcc接受它。为什么三元复制参数?表达式的结果将被丢弃。三元运算符的求值通常可能会导致将任一参数转换为公共类型,但这里的公共类型是a
,因此不需要转换。@MSalters-是否丢弃,它必须格式正确。表达式的结果是一个右值,这意味着在a
上必须可以进行左值到右值的转换。@StoryTeller:不一定不同意您的观点(我必须检查Standardese),但这些转换并非在所有情况下都会发生。例如,您有sizeof(true?a:a())
。