考虑下面显示的代码示例,是 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
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
对象也不需要定义 t
或 d
> 待完成。
该标准甚至包括一个非常相似的示例(请参阅上面的链接)。
所以 MSVC 在这里是错误的。
关于c++ - 非法使用未定义类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77074018/