C++ 错误:请求“..”中的成员“..”,这是非类类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/877523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
error: request for member '..' in '..' which is of non-class type
提问by sarnesjo
I have a class with two constructors, one that takes no arguments and one that takes one argument.
我有一个有两个构造函数的类,一个不带参数,一个带一个参数。
Creating objects using the constructor that takes one argument works as expected. However, if I create objects using the constructor that takes no arguments, I get an error.
使用带一个参数的构造函数创建对象按预期工作。但是,如果我使用不带参数的构造函数创建对象,则会出现错误。
For instance, if I compile this code (using g++ 4.0.1)...
例如,如果我编译此代码(使用 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;
}
... I get the following error:
...我收到以下错误:
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 ()()'
Why is this, and how do I make it work?
为什么会这样,我该如何使它工作?
回答by Mykola Golubyev
Foo foo2();
change to
改成
Foo foo2;
You get the error because compiler thinks of
你得到错误是因为编译器认为
Foo foo2()
as of function declaration with name 'foo2' and the return type 'Foo'.
从名称为“foo2”和返回类型为“Foo”的函数声明开始。
But in that case If we change to Foo foo2
, the compiler might show the error " call of overloaded ‘Foo()' is ambiguous"
.
但在这种情况下,如果我们更改为Foo foo2
,编译器可能会显示错误 " call of overloaded ‘Foo()' is ambiguous"
。
回答by ezdazuzena
Just for the record..
只是为了记录..
It is actually not a solution to your code, but I had the same error message when incorrectly accessing the method of a class instance pointed to by myPointerToClass
, e.g.
它实际上不是您代码的解决方案,但是当我错误地访问由 指向的类实例的方法时,我收到了相同的错误消息myPointerToClass
,例如
MyClass* myPointerToClass = new MyClass();
myPointerToClass.aMethodOfThatClass();
where
在哪里
myPointerToClass->aMethodOfThatClass();
would obviously be correct.
显然是正确的。
回答by Matt
Adding to the knowledge base, I got the same error for
添加到知识库中,我遇到了同样的错误
if(class_iter->num == *int_iter)
Even though the IDE gave me the correct members for class_iter. Obviously, the problem is that "anything"::iterator
doesn't have a member called num
so I need to dereference it. Which doesn't work like this:
即使 IDE 为我提供了正确的 class_iter 成员。显然,问题是"anything"::iterator
没有调用成员,num
所以我需要取消引用它。这不是这样的:
if(*class_iter->num == *int_iter)
...apparently. I eventually solved it with this:
...显然。我最终用这个解决了它:
if((*class_iter)->num == *int_iter)
I hope this helps someone who runs across this question the way I did.
我希望这可以帮助那些像我一样遇到这个问题的人。
回答by Reena Cyril
Parenthesis is not required to instantiate a class object when you don't intend to use a parameterised constructor.
当您不打算使用参数化构造函数时,不需要括号来实例化类对象。
Just use Foo foo2;
只需使用 Foo foo2;
It will work.
它会起作用。
回答by Alexis Lopez Zubieta
I was having a similar error, it seems that the compiler misunderstand the call to the constructor without arguments. I made it work by removing the parenthesis from the variable declaration, in your code something like this:
我遇到了类似的错误,似乎编译器误解了对没有参数的构造函数的调用。我通过从变量声明中删除括号来使它工作,在你的代码中是这样的:
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;
}
回答by solstice333
I ran into a case where I got that error message and had
我遇到了一个情况,我收到了那个错误消息,并有
Foo foo(Bar());
and was basically trying to pass in a temporary Bar object to the Foo constructor. Turns out the compiler was translating this to
并且基本上是试图将临时 Bar 对象传递给 Foo 构造函数。原来编译器正在把它翻译成
Foo foo(Bar(*)());
that is, a function declaration whose name is foo that returns a Foo that takes in an argument -- a function pointer returning a Bar with 0 arguments. When passing in temporaries like this, better to use Bar{}
instead of Bar()
to eliminate ambiguity.
也就是说,一个名为 foo 的函数声明返回一个接受一个参数的 Foo —— 一个函数指针,返回一个带有 0 个参数的 Bar。像这样传入临时词时,最好使用Bar{}
而不是Bar()
消除歧义。
回答by Mo el
If you want to declare a new substance with no parameter (knowing that the object have default parameters) don't write
如果你想声明一个没有参数的新物质(知道对象有默认参数)不要写
type substance1();
but
但
type substance;
回答by yano
Certainly a corner case for this error, but I received it in a different situation, when attempting to overload the assignment operator=
. It was a bit cryptic IMO (from g++ 8.1.1).
当然是这个错误的一个极端情况,但我在尝试重载 assignment 时在不同的情况下收到了它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;
}
I received 2 "identical" errors
我收到了 2 个“相同”的错误
error: request for member ‘i' [and 'f'] in ‘data', which is of non-class type ‘float'
(The equivalent error for clang
is:
error: member reference base type 'float' is not a structure or union
)
(对于等效错误clang
是:
error: member reference base type 'float' is not a structure or union
)
for the lines data.i = data;
and data.f = data;
. Turns out the compiler was confusing local variable name 'data' and my member variable data
. When I changed this to void operator=(T newData)
and data.i = newData;
, data.f = newData;
, the error went away.
对于行data.i = data;
和data.f = data;
。原来编译器混淆了局部变量名 'data' 和我的成员变量data
。当我将其更改为void operator=(T newData)
and data.i = newData;
, 时data.f = newData;
,错误消失了。
回答by abhiarora
@MykolaGolubyev has already given wonderful explanation. I was looking for a solution to do somthing like this MyClass obj ( MyAnotherClass() )
but the compiler was interpreting it as a function declaration.
@MykolaGolubyev 已经给出了精彩的解释。我正在寻找一种解决方案来做这样的事情,MyClass obj ( MyAnotherClass() )
但编译器将其解释为函数声明。
C++11 has braced-init-list. Using this we can do something like this
C++11 有支撑初始化列表。使用这个我们可以做这样的事情
Temp t{String()};
However, this:
然而,这:
Temp t(String());
throws compilation error as it considers t
as of type Temp(String (*)())
.
抛出编译错误,因为它认为t
是 type 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;
}