decltype导致is_same <t,t =“”>失败(相同类型)

时间:2015-08-04 21:32:14

标签: c++ templates rtti typetraits decltype

在下面的代码片段中,我可以使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.

1 个答案:

答案 0 :(得分:7)

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

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

这也解释了using bar = E;给出不同结果的原因。