非积分常数 [英] non-integral constants

查看:132
本文介绍了非积分常数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个非整数常数的头文件,例如。一类。注意常量需要是编译时常量。

  static const std :: string Ten =10; 

这是编译,但不可取,因为每个编译单元现在都有自己的Ten副本。

  const std :: string Ten =10; 

这将编译,但会因为多重定义的Ten而导致链接器错误。

  constexpr std :: string Ten =10s; 

这将工作,但只有当字符串构造函数也是constexpr。这将是,但我不能指望每个非整数常量有一个constexpr构造函数...或者我可以?

  extern const std :: string Ten =10; 

这似乎工作,但恐怕我会得到一个链接器错误,错误。

  inline const std :: string Ten(){return10; } 

这里有一切我想要的,除了一个干净的语法。现在我必须将常量作为函数调用, Ten()

  inline const std :: string =10; 

这似乎是理想的解决方案。当然, inline 变量不被标准允许。





  • 是否有令人信服的理由不允许内联变量?

  • 是否有更好的方法与c ++ 03或将有更好的方法在c ++ 0x?




你是对的

pre> static const std :: string Ten =10;

版本。它将工作,但它将在每个翻译单元中创建一个单独的对象。



不带 static 的版本会有相同的效果。它不会产生链接器错误,但会在每个翻译单元中定义单独的对象。在C ++语言中 const 默认情况下,对象具有内部链接,意味着

  const std :: string Ten =10; //`static`是可选的

静态



包含 extern 和初始化程序的版本

  extern const std :: string Ten =10; //这是一个定义! 

将产生具有外部链接的对象的定义定义,因为存在初始化器)。此版本将导致链接器错误,因为您最终会得到具有外部链接的对象的多个定义 - 违反ODR。



>

为了实现你想达到的效果,你必须在标题中声明文件

  extern const std :: string Ten; //非定义声明

,然后在一个且只有一个实现文件

  extern const std :: string Ten =10 //定义,`extern`可选

(如果常量预先声明为 extern ,那么 extern 在定义中是可选的。它将定义一个具有外部链接的const对象。)


I want a header file with a non-integral constant in it, e.g. a class. Note the constant does not need to be a compile-time constant.

static const std::string Ten = "10";

This compiles but is undesirable as each compilation unit now has its own copy of Ten.

const std::string Ten = "10";

This will compile but will fail with a linker error for multiply defined Ten.

constexpr std::string Ten = "10"s;

This would work but only if the strings constructor was constexpr as well. It will be but I can't count on every non-integral constant to have a constexpr constructor ... or can I?

extern const std::string Ten = "10";

This seems to work but I'm afraid I'll get a linker error if I breath on it wrong.

inline const std::string Ten( ) { return "10"; }

This has everything I want except a clean syntax. Plus now I have to refer the constant as a function call, Ten().

inline const std::string = "10";

This seems to be the ideal solution. Of course inline variables aren't allowed by the standard.

  • Is there something in the c++ standard that says the extern version should work or am I just lucky it works with GCC?
  • Is there a compelling reason not to allow inline variables?
  • Is there a better way with c++03 or will there be a better way in c++0x?

解决方案

You seem to have them mixed up.

You are right about

static const std::string Ten = "10"; 

version. It will "work", but it will create a separate object in each translation unit.

The version without static will have the same effect. It won't produce linker errors, but will define a separate object in each translation unit. In C++ language const objects have internal linkage by default, meaning that

const std::string Ten = "10"; // `static` is optional

is exactly equivalent to the previous version with static.

The version with extern and initializer

extern const std::string Ten = "10"; // it's a definition!

will produce a definition of an object with external linkage (it is a definition because of the presence of an initializer). This version will result in linker errors, since you'll end up with multiple definitions of an object with external linkage - a violation of ODR.

Here's how you can do it:

In order to achieve what you are trying to achieve, you have to declare your constant in the header file

extern const std::string Ten; // non-defining declaration

and then define it (with initializer) in one and only one of the implementation files

extern const std::string Ten = "10"; // definition, `extern` optional

(If the constant is pre-declared as extern, then extern in the definition is optional. Even without an explicit extern it will define a const object with external linkage.)

这篇关于非积分常数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆