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);
}

Click here to compile for yourself.

因为Foo::nestedconstexpr,隐式是const。因此 Foo::nested 的类型是 const E。但是当 x.nested 传递给 show 时,类型衰减并失去其 const 资格。因此 XET::barconst E.

http://coliru.stacked-crooked.com/a/1077cd1df2790423

这也解释了为什么 using bar = E; 给出了不同的结果。