对静态类成员的未定义引用
任何人都可以解释为什么下面的代码不会编译? 至少在g ++ 4.2.4上。
更有趣的是,为什么当我将MEMBER投射到int时会编译?
#include <vector>
class Foo {
public:
static const int MEMBER = 1;
};
int main(){
vector<int> v;
v.push_back( Foo::MEMBER ); // undefined reference to `Foo::MEMBER'
v.push_back( (int) Foo::MEMBER ); // OK
return 0;
}
您需要实际定义静态成员(在类定义之后)。 尝试这个:
class Foo { /* ... */ };
const int Foo::MEMBER;
int main() { /* ... */ }
这应该摆脱未定义的参考。
问题来自于新C ++特性的有趣冲突以及你正在尝试做的事情。 首先,我们来看看push_back
签名:
void push_back(const T&)
它期待对T
类型的对象的引用。 在旧的初始化系统下,存在这样的成员。 例如,下面的代码编译得很好:
#include <vector>
class Foo {
public:
static const int MEMBER;
};
const int Foo::MEMBER = 1;
int main(){
std::vector<int> v;
v.push_back( Foo::MEMBER ); // undefined reference to `Foo::MEMBER'
v.push_back( (int) Foo::MEMBER ); // OK
return 0;
}
这是因为有一个实际的对象存储在那个值中。 但是,如果您切换到指定静态常量成员的新方法(如上所述), Foo::MEMBER
不再是一个对象。 这是一个常数,有点类似于:
#define MEMBER 1
但没有预处理器宏的头痛(并且具有类型安全性)。 这意味着期待参考的矢量不能得到一个。
如果需要定义,C ++标准需要定义静态const成员。
该定义是必需的,例如,如果使用地址。 push_back
通过const引用接受其参数,因此严格地说,编译器需要您的成员的地址,并且您需要在名称空间中定义它。
当你明确地转换常量时,你正在创建一个临时参数,并且这是临时参数(根据标准中的特殊规则)。
这是一个非常有趣的案例,我认为值得提出一个问题,以便std被更改为对于常量成员具有相同的行为!
虽然以一种奇怪的方式,这可以被看作是一元运算符“+”的合法使用。 基本上, unary +
的结果是一个右值,因此适用于rvalues绑定到const引用的规则,我们不使用静态const成员的地址:
v.push_back( +Foo::MEMBER );
链接地址: http://www.djcxy.com/p/72269.html