gpt4 book ai didi

c++ - 模板化类的静态常量

转载 作者:太空狗 更新时间:2023-10-29 21:43:35 26 4
gpt4 key购买 nike

我一直在 gcc 4.8.2 中使用模板类和常量,遇到了一个有趣的链接器错误:

#include <iostream>
using namespace std;

template <class T, int m>
class A {
public:
static const T param = m;
T value;

A(const T &value, const T &dummy = T()) : value(value) {}
};

// Works with this
// template <class T, int m>
// const T A<T, m>::param = m;

template <class T, int m>
A<T, m> operator +(const A<T, m> &a, const A<T, m> &b) {
if (a.param != b.param) exit(1);

// Works if I replace a.param with 0
return A<T, m>(a.value + b.value, a.param);
}

int main() {
A<int, 2> v = A<int, 2>(1) + A<int, 2>(2);
cout << v.value << endl;
return 0;
}

在当前状态下编译代码会出现链接器错误,告诉我 A::param 未定义。

同样在 Visual Studio 2008 中尝试这段代码,它编译和链接没有任何问题。在 gcc 上,当我使用 param 常量的外部声明,或者如果我在指示的行上将 a.param 替换为 0 或什么都没有时,它会编译。

我不明白的是为什么包含if语句的行可以使用a.param而没有编译错误,而我不能通过a.param 到构造函数而不在外部声明它。

所以我的问题是:什么时候需要对外声明paramif语句中的访问和构造函数调用有什么区别?我测试的两个编译器中哪一个在这里做了“正确”的事情,哪个扩展了标准?

再玩一会儿,我意识到当我为 g++ 指定 -O2 标志时它也有效。

最佳答案

template <class T, int m>
class A {
public:
static const T param = m;
T value;

A(const T &value, const T &dummy = T()) : value(value) {}
};

// Works with this
// template <class T, int m>
// const T A<T, m>::param = m;

//gotta define it here!
template <class T, int m>
const T A<T, m>::param;

template <class T, int m>
A<T, m> operator +(const A<T, m> &a, const A<T, m> &b) {
if (a.param != b.param) exit(1);

// Works if I replace a.param with 0
return A<T, m>(a.value + b.value, a.param);
}

int main() {
A<int, 2> v = A<int, 2>(1) + A<int, 2>(2);
std::cout << v.value << std::endl;
return 0;
}

来自 here

If a static data member is of const integral or const enumeration type, you may specify a constant initializer in the static data member's declaration. This constant initializer must be an integral constant expression. Note that the constant initializer is not a definition. You still need to define the static member in an enclosing namespace.

在有效的情况下,编译器不兼容。 Microsoft 不合规,因为 Microsoft 几乎从不合规,带有 -O2 的 g++ 有点有趣,但无论哪种情况,您都没有定义!

编辑:根据经验,我总是在类之外定义我的静态常量成员变量,因为这样我就不必记住它了。在这种情况下,如果 T 不是整数类型(例如 float ),则 A 类将无效。因此,我不会围绕异常制定任何模式,而是倾向于坚持我围绕规则的模式。

关于c++ - 模板化类的静态常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22462266/

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