c++ - std::is_same 对于尚未定义/声明的类

标签 c++ c++14

以下代码是 gcc bug 吗? 检查 T 类型是否为尚未定义的 Circle 类,返回 false。

#include <iostream>

using namespace std;

// uncomment to work
//struct Circle;

struct T_traits
{
    template<typename T>
    constexpr static id() { return is_same<T, class Circle>(); }
};


struct Circle{};

int main()
{
    cout << T_traits::id<Circle>() << "\r\n";
    return 0;
}

最佳答案

return is_same<T, class Circle>();

当您注释掉全局声明时,这实际上会声明一个名为Circle的本地类。 [basic.lookup.elab]/2:

If the elaborated-type-specifier has no nested-name-specifier, and unless the elaborated-type-specifier appears in a declaration with the following form:

     class-key attribute-specifier-seqopt identifier ;

the identifier is looked up according to 3.4.1 but ignoring any non-type names that have been declared.[..]
If the elaborated-type-specifier is introduced by the class-key and this lookup does not find a previously declared type-name [..] the elaborated-type-specifier is a declaration that introduces the class-name as described in 3.3.2.

该查找是简单的非限定名称查找,如第 3.4.1 节中所定义。查找是在 T_traits 的定义上下文中完成的,因为我们不处理依赖的东西,因此永远不会考虑 main 之前的 Circle 声明.
§3.3.2/7(别名[basic.scope.pdecl]/7):

The point of declaration of a class first declared in an elaborated-type-specifier is as follows:

  • for an elaborated-type-specifier of the form

         class-key identifier

    if the elaborated-type-specifier is used in the decl-specifier-seq or parameter-declaration-clause of a function defined in namespace scope, the identifier is declared as a class-name in the namespace that contains the declaration; otherwise, except as a friend declaration, the identifier is declared in the smallest namespace or block scope that contains the declaration. [ Note: These rules also apply within templates. — end note ]

但是,删除 class 关键字也不起作用 - 如前所述,标识符不是依赖的,因此会在定义上下文中查找。如果此查找未找到任何声明,则编译器必须发出诊断 - 即使没有实例化专门化。

关于c++ - std::is_same 对于尚未定义/声明的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27890699/

相关文章:

c++ - 如何查看两个char变量是否彼此相等

c++ - 我无法理解的简单 lambda 函数

c++ - 如何处理为相同输入数据类型返回不同数据类型的 api?

c++ - 富()= 42; <- 这怎么可能?

不使用纯虚函数的 C++ 接口(interface)

c++ - 理性类和 move 语义不起作用

c++ - String 和 Int 之间的模板冲突

c++ - T型的结构范围是什么?

c++ - 无法编译 brian gladman aes 库

c++ - 如何为使用 createwindow 创建的窗口创建自定义背景颜色