gpt4 book ai didi

c++ - 将错误与引用替代命名空间中枚举的静态常量值链接起来

转载 作者:搜寻专家 更新时间:2023-10-31 01:16:17 25 4
gpt4 key购买 nike

我有一些我不明白的链接问题。

这是来源:

#include <iostream>

template < typename T >
struct CompressedEnums {
CompressedEnums () : data(0) {}

T get() const {
return (T)(data);
}

void set(const T& value) {
data = value;
}

unsigned data;
};

namespace Bbs_detail {
enum inner_type { BB0 = 0 , BB1 = 1 , BB2 = 2 };
typedef inner_type E;
};

struct Bbs {
static const size_t size = 3;
typedef Bbs_detail::inner_type inner_type;
typedef inner_type E;
static const Bbs_detail::E BB0 = Bbs_detail::BB0;
static const Bbs_detail::E BB1 = Bbs_detail::BB1;
static const Bbs_detail::E BB2 = Bbs_detail::BB2;
};

std::ostream& operator<<(std::ostream& o, const Bbs::E& e) {
switch(e) {
case Bbs::BB0: o << "BB0"; return o;
case Bbs::BB1: o << "BB1"; return o;
case Bbs::BB2: o << "BB2"; return o;
}
return o;
};

int main(int argc, const char *argv[]) {
CompressedEnums< Bbs::E > l;

l.set(Bbs::BB0);
Bbs::E x = l.get();

std::cout << x << std::endl;

return 0;
}

当我用 -O3 编译它时它工作,但是我用 -O0 得到链接器错误。我已经尝试过 gcc 4.6.2 和 gcc 4.7。

使用 clang 3.0 编译时,无论优化级别如何,我都会遇到链接器错误。

链接器错误:

/tmp/cch116DO.o: In function `main':
test.cxx:(.text+0x8f): undefined reference to `Bbs::BB0'
collect2: error: ld returned 1 exit status

这是因为我在做违法的事情吗?

我认为整数类型的静态 const 成员可以在类中初始化,对吗?

最佳答案

引用C++98标准,9.4.2静态数据成员:

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer. [emphasis mine].

所以你必须定义常量成员是 Alan Stokes 在他的回答中指出的。如果您不这样做,并且编译器设法避免对该变量的任何引用,因为它是常量并且它已经知道值,您可能没有它。但对此无法保证。

奇怪的是,在 C++11 草案中,有一些关于 constexpr 和大括号初始化器的附加说明,然后:

The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program.

然后,在第 3.2 点中,它定义了odr-used 的含义:

A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression (5.19) and the lvalue-to-rvalue conversion (4.1) is immediately applied.

也就是说,在 C++11 中,如果常量成员的所有使用都在常量表达式中,则可以保证不需要成员定义:

关于c++ - 将错误与引用替代命名空间中枚举的静态常量值链接起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9213985/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com