gpt4 book ai didi

c++ - g++4.7.3 和 g++4.8 的 undefined reference ?

转载 作者:行者123 更新时间:2023-11-30 00:53:25 25 4
gpt4 key购买 nike

考虑这段代码:

#include <iostream>
#include <array>

template <typename Type>
struct Constant
{
constexpr Constant(const Type source) : _data({{source}}) {;}
constexpr Constant(const std::array<Type, 1> source) : _data(source) {;}
constexpr Constant<Type> operator()() const {return _data;}
constexpr operator Type() const {return _data[0];}
const std::array<Type, 1> _data;
static constexpr Constant<Type> pi = 3.1415926535897932384626433832795028841971693993751058209749445L;
};

int main(int argc, char* argv[])
{
std::cout<<Constant<double>::pi()<<std::endl;
return 0;
}

我在使用 g++4.7.3g++4.8.0 时遇到编译器错误(这是对 pi 的 undefined reference >(抱歉,这是法语)):

/tmp/cctdvPfq.o: dans la fonction « main »:
main.cpp:(.text.startup+0xd): référence indéfinie vers « Constant<double>::pi »
collect2: erreur: ld a retourné 1 code d'état d'exécution

由于我的系统是全新安装的(第一次使用g++4.7.3g++4.8.0),不知道会不会出现从我的系统配置或编译器。如果来自编译器,问题出在哪里?

编辑:为什么这行得通? (没有数组的版本)

#include <iostream>
#include <array>

template <typename Type>
struct Constant
{
constexpr Constant(const Type source) : _data(source) {;}
constexpr Constant<Type> operator()() const {return _data;}
constexpr operator Type() const {return _data;}
const Type _data;
static constexpr Constant<Type> pi = 3.1415926535897932384626433832795028841971693993751058209749445L;
};

int main(int argc, char* argv[])
{
std::cout<<Constant<double>::pi()<<std::endl;
return 0;
}

最佳答案

您可以避免在 pi 上调用调用运算符(operator),这样它就不会被您的程序odr-used,并且编译器可以处理 pi就像可以内联的值一样,因此不需要定义 static数据成员:

std::cout << Constant<double>::pi << std::endl;
// ^^

或者,您可以继续调用 pi的调用运算符,并在命名空间范围内提供静态数据成员的定义,并使用 Constant<double> 的调用运算符如您的原始代码所示:

template <typename Type>
struct Constant
{
// ...
static constexpr Constant<Type> pi = /* ... */;
};

template<typename Type>
constexpr Constant<Type> Constant<Type>::pi;

根据 C++11 标准的第 9.4.2/3 段:

If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression (5.19). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. —end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

关于c++ - g++4.7.3 和 g++4.8 的 undefined reference ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16467802/

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