在下面的代码片段中,我可以使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);
}
答案 0 :(得分:7)
由于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;
给出不同结果的原因。