decltype 导致 is_same<T, T> 失败(相同类型)
decltype causes is_same<T, T> to fail (same type)
在下面的代码片段中,我可以让 is_same 声明两种类型是不同的,即使它们具有相同的错位名称,这在 GCC 和 clang 中都有效。这仅在我使用 decltype 时发生,如果我使用注释掉的行,则编译器认为这两种类型与预期的相同。这是某种符合标准的预期行为,还是一个错误?
#include <iostream>
#include <type_traits>
#include <typeinfo>
template <typename T, typename X>
void show(T, X)
{
auto same = std::is_same<typename T::bar, X>::value;
std::cout << "They are " << (same ? "the same" : "NOT the same") << std::endl;
// the same string is always printed both times
std::cout << typeid(typename T::bar).name() << std::endl;
std::cout << typeid(X).name() << std::endl;
}
template <typename T>
struct Foo
{
static constexpr struct E {} nested {};
using bar = decltype(nested); // They are NOT the same
// using bar = E; // They are the same
};
int main()
{
Foo<int> x;
show(x, x.nested);
}
因为Foo::nested
是constexpr
,隐式是const
。因此 Foo::nested
的类型是 const E
。但是当 x.nested
传递给 show
时,类型衰减并失去其 const
资格。因此 X
是 E
但 T::bar
是 const E
.
见http://coliru.stacked-crooked.com/a/1077cd1df2790423
这也解释了为什么 using bar = E;
给出了不同的结果。
在下面的代码片段中,我可以让 is_same 声明两种类型是不同的,即使它们具有相同的错位名称,这在 GCC 和 clang 中都有效。这仅在我使用 decltype 时发生,如果我使用注释掉的行,则编译器认为这两种类型与预期的相同。这是某种符合标准的预期行为,还是一个错误?
#include <iostream>
#include <type_traits>
#include <typeinfo>
template <typename T, typename X>
void show(T, X)
{
auto same = std::is_same<typename T::bar, X>::value;
std::cout << "They are " << (same ? "the same" : "NOT the same") << std::endl;
// the same string is always printed both times
std::cout << typeid(typename T::bar).name() << std::endl;
std::cout << typeid(X).name() << std::endl;
}
template <typename T>
struct Foo
{
static constexpr struct E {} nested {};
using bar = decltype(nested); // They are NOT the same
// using bar = E; // They are the same
};
int main()
{
Foo<int> x;
show(x, x.nested);
}
因为Foo::nested
是constexpr
,隐式是const
。因此 Foo::nested
的类型是 const E
。但是当 x.nested
传递给 show
时,类型衰减并失去其 const
资格。因此 X
是 E
但 T::bar
是 const E
.
见http://coliru.stacked-crooked.com/a/1077cd1df2790423
这也解释了为什么 using bar = E;
给出了不同的结果。