关于c ++:error:请求’..’中的成员’..’,它是非类型的


error: request for member '..' in '..' which is of non-class type

我有一个类,有两个构造函数,一个不带参数,另一个带参数。

使用接受一个参数的构造函数创建对象可以按预期工作。但是,如果我使用不带参数的构造函数创建对象,我会得到一个错误。

例如,如果我编译这段代码(使用G++4.0.1)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Foo
{
  public:
    Foo() {};
    Foo(int a) {};
    void bar() {};
};

int main()
{
  // this works...
  Foo foo1(1);
  foo1.bar();

  // this does not...
  Foo foo2();
  foo2.bar();

  return 0;
}

…我得到以下错误:

1
2
nonclass.cpp: In function ‘int main(int, const char**):
nonclass.cpp:17: error: request for member ‘bar’ in ‘foo2’, which is of non-class type ‘Foo ()()

这是为什么,我如何使它工作?


1
Foo foo2();

改为

1
Foo foo2;

因为编译器认为

1
Foo foo2()

从名为"foo2"且返回类型为"foo"的函数声明开始。

但在这种情况下,如果我们改为Foo foo2,编译器可能会显示错误" call of overloaded ‘Foo()’ is ambiguous"


只是为了记录……

实际上,这不是您的代码的解决方案,但我在错误地访问myPointerToClass所指向的类实例的方法时收到了相同的错误消息,例如。

1
2
MyClass* myPointerToClass = new MyClass();
myPointerToClass.aMethodOfThatClass();

哪里

1
myPointerToClass->aMethodOfThatClass();

显然是正确的。


加上知识库,我得到了相同的错误

1
if(class_iter->num == *int_iter)

即使IDE给了我正确的班级成员。显然,问题是"anything"::iterator没有名为num的成员,所以我需要取消引用。不是这样的:

1
if(*class_iter->num == *int_iter)

显然…我最终解决了这个问题:

1
if((*class_iter)->num == *int_iter)

我希望这能帮助像我这样遇到这个问题的人。


当不打算使用参数化构造函数时,不需要括号来实例化类对象。

只需使用foo foo2;

它会起作用的。


我也遇到了类似的错误,似乎编译器没有参数就误解了对构造函数的调用。我通过从变量声明中删除括号使其生效,在您的代码中类似于:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Foo
{
  public:
    Foo() {};
    Foo(int a) {};
    void bar() {};
};

int main()
{
  // this works...
  Foo foo1(1);
  foo1.bar();

  // this does not...
  Foo foo2; // Without"()"
  foo2.bar();

  return 0;
}


我遇到了一个案例,我收到了错误消息

1
Foo foo(Bar());

基本上是试图将一个临时的bar对象传递给foo构造函数。结果编译器把这个翻译成

1
Foo foo(Bar(*)());

也就是说,一个函数声明,其名称为foo,它返回接受参数的foo——返回带有0个参数的条的函数指针。在传递这样的临时文件时,最好使用Bar{},而不是Bar(),以消除歧义。


当然,这是一个很棘手的错误,但我在另一种情况下收到了它,当时我试图重载分配operator=。这是一个有点神秘的IMO(从G++8.1.1)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <cstdint>

enum DataType
{
  DT_INT32,
  DT_FLOAT
};

struct PrimitiveData
{
  union MyData
  {
    int32_t i;
    float f;
  } data;

  enum DataType dt;

  template<typename T>
  void operator=(T data)
  {
    switch(dt)
    {
      case DT_INT32:
      {
        data.i = data;
        break;
      }
      case DT_FLOAT:
      {
        data.f = data;
        break;
      }
      default:
      {
        break;
      }
    }
  }
};

int main()
{
  struct PrimitiveData pd;
  pd.dt = DT_FLOAT;
  pd = 3.4f;

  return 0;
}

我收到两个"相同"的错误

1
error: request for member ‘i’ [and 'f'] in ‘data’, which is of non-class type ‘float

(clang的等效误差为:error: member reference base type 'float' is not a structure or union

用于data.i = data;data.f = data;线。结果发现编译器混淆了局部变量名"data"和我的成员变量data。当我把这个改成void operator=(T newData)data.i = newData;data.f = newData;时,错误就消失了。


如果您想要声明一个没有参数的新物质(知道对象有默认参数),不要写

1
 type substance1();

但是

1
 type substance;