我对 decltype(dependent-expression) 确定“唯一依赖类型”的效果有疑问。
这个其他讨论stackoverflow_link涉及这个主题,但它只关注声明和定义之间的匹配。
在以下示例中godbolt_link
#include <iostream>
#include <type_traits>
template<typename T>
struct X{};
template<typename T>
void f(){
T t;
X<decltype(t+t)> a;
X<T> b;
std::cout << std::boolalpha << std::is_same_v<decltype(a),decltype(b)> << std::endl;
}
int main(){
f<int>();
}
gcc 14.2 的输出是“true”,这意味着与 T 相比,decltype(t+t) 不被视为不同的类型(我喜欢这个)。
所以,我正在考虑,当标准阅读有关依赖表达式的 decltype(e) 时,它正在讨论类型等效性,并要求两个等效的模板 ID 引用相同的模板实例化,这意味着实际上没有规则即使 decltype(e) 拥有“正式”唯一(依赖)类型,也禁止考虑相同的实例化。
这是一个正确的想法,还是标准中存在其他一些明确的方面导致我的示例中的“true”?它应该是关于类型“依赖”的影响,和/或关于 decltype(e) 的依赖类型的术语“唯一”的解释。
decltype
有两种不同的工作方式。 decltype(variable)
返回变量的声明类型。 如果您不执行 decltype(variable)
,则 decltype(expression)
返回表达式的类型。
表达式的类型不包括右值/左值类别之类的东西。
T t;
X<decltype(t+t)> a;
X<T> b;
std::cout << std::boolalpha << std::is_same_v<decltype(a),decltype(b)> << std::endl;
此返回 true,因为
int+int
的类型是 int
。 所以 X<int>
和 X<decltype(2+3)>
是同一类型。 仅此而已。
struct Y {
friend double operator+(Y,Y) { return 0. }
};
如果你这样做:
f<Y>();
打印
false
,因为 Y{}+Y{}
是 double
类型。
这与依赖类型完全无关。