首页 文章

错误:请求'..'中的成员'..',这是非类型的

提问于
浏览
362

我有一个带有两个构造函数的类,一个不带参数,一个带一个参数 .

使用带有一个参数的构造函数创建对象可以按预期工作 . 但是,如果我使用不带参数的构造函数创建对象,则会出错 .

例如,如果我编译此代码(使用g 4.0.1)...

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;
}

...我收到以下错误:

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 ()()’

为什么这样,我如何使其工作?

8 回答

  • 4
    Foo foo2();
    

    改成

    Foo foo2;
    

    你得到错误,因为编译器认为

    Foo foo2()
    

    具有名称'foo2'的函数声明和返回类型'Foo' .

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

  • 549

    仅供记录..

    它实际上不是您的代码的解决方案,但是当错误地访问 myPointerToClass 指向的类实例的方法时,我有相同的错误消息,例如

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

    哪里

    myPointerToClass->aMethodOfThatClass();
    

    显然是正确的 .

  • 9

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

    if(class_iter->num == *int_iter)
    

    尽管IDE为我提供了class_iter的正确成员 . 显然,问题是 "anything"::iterator 没有名为 num 的成员所以我需要取消引用它 . 哪个不能这样工作:

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

    ...很明显 . 我最终解决了这个问题:

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

    我希望这可以帮助那些以我的方式遇到这个问题的人 .

  • 1

    我遇到了类似的错误,似乎编译器误解了没有参数的构造函数的调用 . 我通过从变量声明中删除括号来实现它,在你的代码中是这样的:

    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;
    }
    
  • 4

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

    只需使用 Foo foo2;

    它会工作 .

  • 37

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

    Foo foo(Bar());
    

    并且基本上是尝试将临时Bar对象传递给Foo构造函数 . 事实证明编译器正在将其转换为

    Foo foo(Bar(*)());
    

    也就是说,一个名为foo的函数声明返回一个接受参数的Foo - 一个返回带有0个参数的Bar的函数指针 . 在传递这样的临时值时,最好使用 Bar{} 而不是 Bar() 来消除歧义 .

  • 0

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

    type substance1();
    

    type substance;
    
  • 0

    当然是这个错误的一个极端情况,但是当我试图重载赋值 operator= 时,我在不同的情况下收到了它 . 这是一个有点神秘的IMO(来自g 8.1.1) .

    #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;
    }
    

    我收到了2个“完全相同”的错误

    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; 时,错误消失了 .

相关问题