错误:请求成员'在& # 39;. . & # 39;哪个是非类类型的

我有一个有两个构造函数的类,一个不接受参数,一个接受一个参数。

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

例如,如果我编译这段代码(使用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 ()()’

为什么会这样,我该怎么做呢?

626540 次浏览
Foo foo2();

改变

Foo foo2;

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

Foo foo2()

如函数声明名称为'foo2',返回类型为'Foo'。

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

只是为了记录…

它实际上不是一个解决方案,你的代码,但我有相同的错误消息时,不正确地访问一个类实例的方法由myPointerToClass,例如。

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

在哪里

myPointerToClass->aMethodOfThatClass();

显然是正确的。

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

if(class_iter->num == *int_iter)

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

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

…很明显。我最终用这个解决了这个问题:

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

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

我有一个类似的错误,似乎编译器误解了没有参数的构造函数的调用。我通过从变量声明中删除圆括号来使它工作,在你的代码中是这样的:

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

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

使用Foo foo2;即可

它会起作用的。

我遇到了这样的情况,我得到了错误信息

Foo foo(Bar());

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

Foo foo(Bar(*)());

也就是说,一个名为foo的函数声明,它返回一个带参数的foo——一个函数指针,返回一个带0个参数的Bar。当像这样传递临时对象时,最好使用Bar{}而不是Bar()来消除歧义。

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

 type substance1();

 type substance;

当然是这个错误的极端情况,但我在不同的情况下收到它,当试图重载赋值operator=时。在我看来,它有点神秘(来自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的等效错误是: # EYZ0) < / p >

对于行data.i = data;data.f = data;。原来编译器混淆了局部变量名称“data”和我的成员变量data。当我把它改为void operator=(T newData)data.i = newData;data.f = newData;时,错误就消失了。

@MykolaGolubyev已经给出了精彩的解释。我正在寻找一个解决方案来做这样的MyClass obj ( MyAnotherClass() ),但编译器将其解释为函数声明。

c++ 11有braced-init-list。用这个我们可以做这样的事情

Temp t{String()};

然而,这种:

Temp t(String());

当它认为t类型为Temp(String (*)())时,抛出编译错误。

#include <iostream>


class String {
public:
String(const char* str): ptr(str)
{
std::cout << "Constructor: " << str << std::endl;
}
String(void): ptr(nullptr)
{
std::cout << "Constructor" << std::endl;
}
virtual ~String(void)
{
std::cout << "Destructor" << std::endl;
}


private:
const char *ptr;
};


class Temp {
public:
Temp(String in): str(in)
{
std::cout << "Temp Constructor" << std::endl;
}


Temp(): str(String("hello"))
{
std::cout << "Temp Constructor: 2" << std::endl;
}
virtual ~Temp(void)
{
std::cout << "Temp Destructor" << std::endl;
}


virtual String get_str()
{
return str;
}


private:
String str;
};


int main(void)
{
Temp t{String()}; // Compiles Success!
// Temp t(String()); // Doesn't compile. Considers "t" as of type: Temp(String (*)())
t.get_str(); // dummy statement just to check if we are able to access the member
return 0;
}