Vin*_*ent 1 c++ compiler-errors g++ undefined-reference c++11
考虑以下代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
我得到一个编译器错误g++4.7.3和g++4.8.0(这是一个未定义的引用pi(抱歉,它是法语)):
/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
Run Code Online (Sandbox Code Playgroud)
由于我的系统是全新安装(第一次使用g++4.7.3和g++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;
}
Run Code Online (Sandbox Code Playgroud)
您可以避免调用调用操作符pi,以便程序不会使用它,并且编译器可以pi像处理可以内联的值一样处理,因此不需要该数据成员的定义static:
std::cout << Constant<double>::pi << std::endl;
// ^^
Run Code Online (Sandbox Code Playgroud)
或者,您可以继续调用pi调用操作符,并在命名空间范围内提供静态数据成员的定义,并使用Constant<double>原始代码中的call运算符:
template <typename Type>
struct Constant
{
// ...
static constexpr Constant<Type> pi = /* ... */;
};
template<typename Type>
constexpr Constant<Type> Constant<Type>::pi;
Run Code Online (Sandbox Code Playgroud)
根据C++ 11标准的第9.4.2/3段:
如果非易失性
const静态数据成员是整数类型或枚举类型,则其在类定义中的声明可以指定一个大括号或大小为初始化器,其中作为赋值表达式的每个initializer子句 都是一个常量表达式(5.19) .可以使用说明符在类定义中声明文字类型的静态数据成员; 如果是这样,它的声明应指定一个大括号或等于初始化器 ,其中作为赋值表达式的每个initializer子句都是一个常量表达式.[注意:在这两种情况下,成员可能会出现在常量表达式中.-end note] 如果在程序中使用odr-used(3.2)并且命名空间作用域定义不包含初始化程序,则仍应在命名空间作用域中定义该成员.constexpr
| 归档时间: |
|
| 查看次数: |
190 次 |
| 最近记录: |