C++ std::对于尚未定义/声明的类是否相同

C++ std::对于尚未定义/声明的类是否相同,c++,c++14,C++,C++14,下面的代码是gcc错误吗? 检查T类型是否为尚未定义的类圆,返回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>(); } };

下面的代码是gcc错误吗? 检查T类型是否为尚未定义的类圆,返回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;
}
#包括
使用名称空间std;
//取消对工作的注释
//结构圆;
结构T_特征
{
模板
constexpr static id(){return is_same();}
};
结构圆{};
int main()
{
cout
返回值是相同的();
当您注释掉全局声明时,这实际上会声明一个名为
Circle
的本地类。[basic.lookup.elab]/2:

如果详细说明的类型说明符没有嵌套的名称说明符,以及 除非详细说明的类型说明符出现在带有 以下表单:

类密钥 属性说明符seqopt标识符 根据3.4.1查找标识符,但忽略任何非类型 已声明的名称。[..]
如果类键引入了详细的类型说明符 此查找未找到以前声明的类型名 […]详细说明的类型说明符是 介绍3.3.2中所述的类名。

查找是§3.4.1中定义的简单的非限定名称查找。查找是在
T_traits
的定义上下文中完成的,因为我们不处理依赖的内容,因此从不考虑
main
之前的
圆圈的声明。
§3.3.2/7(别名[基本范围pdecl]/7):

类的声明点,在 详细的类型说明符如下所示:

  • 对于窗体的详细类型说明符

    类密钥标识符

    如果在中使用了详细的类型说明符 decl说明符seq或命名空间范围中定义的函数的参数声明子句,标识符声明为 包含声明的命名空间中的类名;否则,除作为友元声明外,标识符在包含声明的最小命名空间或块作用域中声明 声明。[注意:这些规则也适用于模板。-结束 注意]


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

删除
。您正在声明一个新的、不同的类型。[temp.res]/p10需要一个诊断,如果非依赖名称在定义时不在范围内。@T.C.我想我以前看到过这句话,但我没有真正记住它。干杯。
return is_same<T, class Circle>();