c++ - 三元允许隐式调用显式复制构造函数吗?

标签 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 并且应该会失败,因为复制构造函数是显式的,但是 gcc 可以很好地编译它并创建一个拷贝。 Clang 按预期吐出一个错误。

这是 gcc 中的错误吗?

我在 c++17 模式下使用 gcc 8.1 和 clang 7.0,但我也在 compiler explorer 中尝试了所有版本的 gcc在 c++98 模式下,它们的行为都相同。

最佳答案

Clang 拒绝它是对的,它确实是一个 GCC 错误。为简单起见,我将引用 n4659(我必须与 C++17 标准最接近的文档)。

首先,您示例中条件表达式的类型,由 [expr.cond] ¶6 指定必须是 A 类型的纯右值。

现在,根据[expr.cond] ¶7 ,强调我的:

Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are performed on the second and third operands.

a 必须能够进行左值到右值的转换。 [conv.lval] ¶3.2 中指定了 a (再次强调我的)作为

Otherwise, if T has a class type, the conversion copy-initializes the result object from the glvalue.

A 复制 A 的初始化,在任何情况下,都应该在重载决议中选择一个转换构造函数([over.match.copy] ¶1.1):

The converting constructors of T are candidate functions.

并且显式复制构造函数不是转换构造函数([class.conv.ctor] ¶3)

A non-explicit copy/move constructor ([class.copy]) is a converting constructor.

符合标准的 C++ 实现不能接受您编写的条件表达式的格式正确。

关于c++ - 三元允许隐式调用显式复制构造函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52720175/

相关文章:

linux - 如何在 Linux 中生成核心转储文件?

c++ - std::call_once() 在 callable 抛出第一次调用后在第二次调用时挂起

c++ - lambda捕获的"this"不正确。 GCC 编译器错误?

C++ 对象创建和列表

javascript - 如何使用cocos creator在Cocos2d-X/Cocos2d-JS中调用javascript函数并从c++传递值

c++ - Opengl:如何影响纹理平面上的照明?

C++将文本写入文件,如何多行

c - 非常简单的错误;我可能忘记了分号

c++ - "Move or throw"使用三元运算符

c++ - 当 C++ 从函数的返回值将元素存储到 std::vector 时出现意外结果