为什么只能在C++类中初始化整数或枚举类型?

Giu*_*Pes 9 c++ int enums c++11

我不明白为什么C++只允许在类声明中定义整数类型和枚举(枚举也是一个整数类型).而所有其他类型,包括浮点类型(即double和float),必须在类声明之外定义.显然必须是这个的原因,但我无法弄清楚.

代码示例:

#include <iostream>

using namespace std;

struct Node {

  static const int c = 0;  // Legal Definition 
  static const long l = 0l; // Legal Definition 
  static const short s = 0; // Legal Definition 

  static const float f = 0.0f; // Illegal definition 
  static const string S = "Test"; // Illegal definition 

  static const string JOB_TYPE; // Legal declaration
  static const float f; // Legal declaration 
  static const double d; // Legal declaration 
};

const string Node::JOB_TYPE = "Test"; // correct definition
const float Node::f = 0.0f;  // correct definition 
const double Node::d = 0.0;  // correct definition 

int main() {

  cout << Node::c << endl;
  cout << Node::c << endl;

  cout << Node::JOB_TYPE << endl;

  cout << Node::f << endl;

}
Run Code Online (Sandbox Code Playgroud)

Mat*_*son 8

这里的关键原因是整数类型(enum因为在编译器中这些变成某种整数)可以简单地替换并直接用作常量.

换句话说,struct S { static const int x = 42;}如果编译器看到S::x,它可以立即用42生成的代码中的常量替换它.同样不(始终)适用于float,当然不适用于构造函数相关类型,例如std::string- 编译器无法在std::string不调用new(或std::string::allocator)的情况下分配内存.因此,对于必须"构造"和/或具有更复杂标准的常量,可以使用它们(想想没有硬件支持浮点的处理器 - 加载和存储浮点值的函数调用,等),语言不能规定它应该被允许这样做.

如果包含struct Node声明static const std::string S = "test";,编译器应存储多少个位置Node::S?它应该使用哪一个,当它最终将你的三个翻译单元链接到一个程序时 - 或者它应该使用不同的程序?会发生什么,然后,如果你const_castNode::S和修改呢?后者假设你有一个环境,这不会导致崩溃,这是完全合理的,虽然这是未定义的行为,但我不确定编译器是否应该像在每个翻译单元中使用不同的值一样奇怪那个案子......

编辑:正如评论中所提到的,C++ 11确实允许以类似的方式使用更多类型,因此随着编译器和硬件技术的改进,这些限制正在放松.我怀疑你是否能够static const std::map<X, Y> a = { ... }',因为这是一个相当复杂的数据类型来构建......