错误C2327:不是类型名称,静态或枚举 [英] error C2327: not a type name, static, or enumerator

查看:215
本文介绍了错误C2327:不是类型名称,静态或枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在窗口上遇到错误C2327。

我减少了我的代码,并在测试程序中遇到类似的错误

 code> #include< boost / intrusive / list.hpp> 
#include< iostream>

class Test {
protected:
typedef test self_type;
boost :: intrusive :: list_member_hook<> order_hook;
public:
typedef boost :: intrusive :: member_hook< self_type,
boost :: intrusive :: list_member_hook<>,
& Test :: order_hook> order_hook_type;
};

这在g ++上正常工作,但在Windows上它会给出以下错误:

  test.cpp(11):错误C2327:'Test :: order_hook':不是类型名称,静态或枚举
test.cpp (11):error C2065:'order_hook':undeclared identifier

tl; dr:Visual Studio有一个错误:你的代码是合法的。







[C ++ 11:14.3 .2 / 1]: 非模板,非模板模板参数的模板参数 对于积分或枚举类型的非类型的模板参数,是> p>


  • 类型 template-parameter ;或

  • 非类型模板参数的名称;或

  • 常量表达式(5.19),指定具有静态存储持续时间和外部或内部链接或具有外部或内部链接的函数的对象的地址,包括函数模板和函数 template-ids ,但不包括非静态类成员,表示(忽略括号)为&除了如果名称引用函数或数组则可以省略& ,并且如果对应的 > template-parameter 是一个参考;或

  • 一个常量表达式,计算结果为空指针值(4.10);或

  • 一个常量表达式,计算结果为空成员指针值(4.11);或

  • 指向5.3.1 中描述的成员的指针。



[C ++ 11:5.3.1 / 3]:一元& operator是指向其操作数的指针。 操作数应为左值或 qualified-id 。如果操作数是一个 C m qualified-id c>,类型 T ,结果具有类型 C > T ,并且是指定 C :: m 的prvalue。 [..]



[C ++ 11:3.4.3.1/1]:如果 qualified-id nested-name-specifier 指定类,则 nested-name-specifier 在类(10.2)的范围内查找,除了下面列出的情况。名称应代表该类或其基类之一(第10条)的一个或多个成员。 [注意: 类成员
在其潜在范围内的任何时候都可以使用 qualified-id 强>。 -end note] 上述名称查询规则的例外情况如下:




  • 根据3.4.3中的规定查找析构函数名; conversion-function-id

  • / em>在类成员访问中以与 conversion-type-id 相同的方式查找(参见3.4.5);

  • 在发生整个 postfix-expression 的上下文中查找模板id 模板参数

  • 在使用声明(7.3.3)中指定的名称的查找也查找隐藏在同一范围内的类或枚举名称(3.3.10)。


这里没有任何例外适用,所以我们看看类成员的潜在范围:


[C ++ 11:3.3.7 / 1]:以下规则描述了在类中声明的名称的范围。 / p>


  1. 在类中声明的名称的潜在范围不仅包括名称声明点之后的声明区,而且还包括所有函数体,非静态数据成员的括号或等于初始值,以及该类中的默认参数(包括嵌套类中的此类事件)。

  2. em>


GCC 正确编译并执行以下测试用例

 模板< typename B,int B :: * PTM> 
struct A {};

struct B
{
int x;

typedef A< B,& B :: x>一个;
};

int main(){
B b;
}

而Visual Studio 2012 Express错误输出:


1> ------构建开始:项目:test1,配置:调试Win32 ------

1> test .cpp

1> f:\documents \visual studio 2012 \projects\test1\test1\test.cpp(8):error C2327:'B :: x':is不是类型名称,静态或枚举

1> f:\documents \visual studio 2012 \projects\test1\test1\test.cpp(8):error C2065: x':未声明标识符

1> f:\documents \visual studio 2012 \projects\test1\test1\test.cpp(8):error C2975:'PTM':invalid 'A'的模板参数,期望的编译时常数表达式

1> f:\documents\visual studio 2012 \projects\test1\test1\test.cpp(1):请参见PTM的声明

========== Build:0成功,1失败,0最新,0跳过==========



I am facing "error C2327" on windows.
I reduced my code and get similar error with test program

#include <boost/intrusive/list.hpp>
#include <iostream>

class Test {
protected:
         typedef Test self_type;
         boost::intrusive::list_member_hook<> order_hook;
public:
         typedef boost::intrusive::member_hook<self_type,
                            boost::intrusive::list_member_hook<>,
                            & Test::order_hook > order_hook_type;
};

This works fine on g++ but on windows it's giving following error:

test.cpp(11) : error C2327: 'Test::order_hook' : is not a type name, static, or enumerator
test.cpp(11) : error C2065: 'order_hook' : undeclared identifier

Please help. What i am missing for windows?

解决方案

tl;dr: Visual Studio has a bug: your code is legal.


[C++11: 14.3.2/1]: A template-argument for a non-type, non-template template-parameter shall be one of:

  • for a non-type template-parameter of integral or enumeration type, a converted constant expression (5.19) of the type of the template-parameter; or
  • the name of a non-type template-parameter; or
  • a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as & id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; or
  • a constant expression that evaluates to a null pointer value (4.10); or
  • a constant expression that evaluates to a null member pointer value (4.11); or
  • a pointer to member expressed as described in 5.3.1.

[C++11: 5.3.1/3]: The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id. If the operand is a qualified-id naming a non-static member m of some class C with type T, the result has type "pointer to member of class C of type T" and is a prvalue designating C::m. [..]

[C++11: 3.4.3.1/1]: If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-name-specifier is looked up in the scope of the class (10.2), except for the cases listed below. The name shall represent one or more members of that class or of one of its base classes (Clause 10). [ Note: A class member can be referred to using a qualified-id at any point in its potential scope (3.3.7). —end note ] The exceptions to the name lookup rule above are the following:

  • a destructor name is looked up as specified in 3.4.3;
  • a conversion-type-id of a conversion-function-id is looked up in the same manner as a conversion-type-id in a class member access (see 3.4.5);
  • the names in a template-argument of a template-id are looked up in the context in which the entire postfix-expression occurs.
  • the lookup for a name specified in a using-declaration (7.3.3) also finds class or enumeration names hidden within the same scope (3.3.10).

None of the exceptions apply here, so we look at the class member's "potential scope":

[C++11: 3.3.7/1]: The following rules describe the scope of names declared in classes.

  1. The potential scope of a name declared in a class consists not only of the declarative region following the name’s point of declaration, but also of all function bodies, brace-or-equal-initializers of non-static data members, and default arguments in that class (including such things in nested classes).
  2. [..]

GCC correctly compiles and executes the following testcase:

template <typename B, int B::* PTM>
struct A {};

struct B
{
    int x;

    typedef A<B, &B::x> a;
};

int main() {
    B b;
}

whereas Visual Studio 2012 Express incorrectly errors out:

1>------ Build started: Project: test1, Configuration: Debug Win32 ------
1> test.cpp
1>f:\documents\visual studio 2012\projects\test1\test1\test.cpp(8): error C2327: 'B::x' : is not a type name, static, or enumerator
1>f:\documents\visual studio 2012\projects\test1\test1\test.cpp(8): error C2065: 'x' : undeclared identifier
1>f:\documents\visual studio 2012\projects\test1\test1\test.cpp(8): error C2975: 'PTM' : invalid template argument for 'A', expected compile-time constant expression
1> f:\documents\visual studio 2012\projects\test1\test1\test.cpp(1) : see declaration of 'PTM'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

这篇关于错误C2327:不是类型名称,静态或枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆