c++ - 非法使用未定义类型

标签 c++ language-lawyer c++20 compiler-bug

考虑下面显示的代码示例,是 decltype(h{}.t());法律表述? C++20 标准中的哪条具体规则允许或禁止这种情况?

struct d;
struct h { static auto t() -> d; };

using a = decltype(h::t());             // all ok
using b = decltype(decltype(h{})::t()); // all ok
using c = decltype(h{}.t());            // clang ok, gcc ok, msvc nope

Live example


MSVC 产生的错误消息:

<source>(6): error C2027: use of undefined type 'd'
<source>(1): note: see declaration of 'd'

在偶然发现 MSVC 的另一个错误之后,我实际上发现了 MSVC 异常行为的解决方法。只需为类型 h 提供用户定义的默认构造函数即可,MSVC不再提示d未定义。

struct d;
struct h {
    static auto t() -> d;
    h() = default;
};
using c = decltype(h{}.t()); // all ok

但是,当跳过使用 h 时,问题似乎仍然存在。的构造函数,就像使用 std::declval 一样例如(如: decltype(std::declval<h>().t()); )。另外,请注意,通过提供用户定义的默认构造函数,即使是默认的,也会导致 h不再被视为聚合类型。

最佳答案

明确允许 decltype 的纯右值表达式操作数的类型不完整。在这种情况下,特殊情况下不会应用临时物化,因此也不需要 d 的析构函数(这需要 d 完整才能查找析构函数)。所以 d 不需要是完整的。标准引用见[dcl.type.decltype]/2 .

函数t也可能是未定义的,因为在decltype操作数中使用并不在潜在评估的表达式中使用,因此不是odr使用。

使用 h{} 构造 h 对象也不需要定义 td > 待完成。

该标准甚至包括一个非常相似的示例(请参阅上面的链接)。

所以 MSVC 在这里是错误的。

关于c++ - 非法使用未定义类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77074018/

相关文章:

c++ - OpenCV - 如何计算照片中的物体?

c++ - 将命名空间的成员重新定义到嵌套的内联命名空间中

python - 在 Python 3.2 中, "lambda"是否被视为 "keyword,"和 "operator"或两者?

c++ - std::string 最终会成为我们的编译时字符串吗?

c++ - 如何使循环队列线程安全?

c++ - 如何使用 if 语句更改变量值

c - 我们不能用指针进行什么操作?

c++ - 如何通过可变参数模板表达概念?

c++ - 嵌套概念多态模板

c++ - 循环双向链表复制构造函数 C++