首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对g++4.7.3和g++4.8的引用是否未定义?

对g++4.7.3和g++4.8的引用是否未定义?
EN

Stack Overflow用户
提问于 2013-05-10 01:40:59
回答 1查看 196关注 0票数 1

考虑下面的代码:

代码语言:javascript
复制
#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的引用(对不起,它是法语的引用)时遇到一个编译器错误):

代码语言:javascript
复制
/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),我不知道它是来自我的系统配置还是来自编译器。如果它来自编译器,那么问题出在哪里?

编辑:为什么这是有效的?(不带数组的版本)

代码语言:javascript
复制
#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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-10 01:43:31

您可以避免调用pi上的call操作符,这样程序就不会使用,并且编译器可以将pi视为可以内联的值,从而不需要定义该static数据成员:

代码语言:javascript
复制
std::cout << Constant<double>::pi << std::endl;
//                             ^^

或者,您可以继续调用pi的call操作符,并在名称空间范围内提供静态数据成员的定义,并像在原始代码中一样使用Constant<double>的call操作符:

代码语言:javascript
复制
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段:

如果非易失性const静态数据成员是整型或枚举类型,则其在类定义中的声明可以指定一个花括号或相等初始化器,在该初始化器中,作为赋值表达式的每个初始化器子句都是常量表达式(5.19)。可以在类定义中使用constexpr说明符声明文本类型的静态数据成员;如果是这样,则其声明应指定一个花括号或相等初始化器,在该初始化器中,每个作为赋值表达式的初始化器子句都是常量表达式。注意:在这两种情况下,成员都可能出现在常量表达式中。-end注意:如果在程序中使用了 (3.2),则仍应在命名空间作用域中定义该成员,并且命名空间作用域定义不应包含odr

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16467802

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档