我有一个有两个构造函数的类,一个不接受参数,一个接受一个参数。
使用带一个参数的构造函数创建对象可以正常工作。但是,如果我使用不带参数的构造函数创建对象,就会得到一个错误。
例如,如果我编译这段代码(使用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 ()()’
为什么会这样,我该怎么做呢?
当然是这个错误的极端情况,但我在不同的情况下收到它,当我试图重载赋值操作符=时。在我看来,它有点神秘(来自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的等效误差为:
错误:成员引用基类型'float'不是结构体或并体)
对于行数据。I =数据;和数据。F =数据;。原来编译器混淆了局部变量名称“数据”和我的成员变量数据。当我把这个改为void operator=(T newData)和data。i = newData;, data。f = newData;,错误消失。
@MykolaGolubyev已经给出了精彩的解释。我正在寻找一个解决方案来做这样的MyClass obj (MyAnotherClass()),但编译器将其解释为函数声明。
c++ 11有括号-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;
}