C++ C++;-是否将常量幻数放入命名空间

C++ C++;-是否将常量幻数放入命名空间,c++,namespaces,constants,magic-numbers,C++,Namespaces,Constants,Magic Numbers,我总是使用#define在cpp文件开头的某个地方定义幻数。我想把它改成constnumbers。(在cpp文件中声明/定义了globals。)这是个好主意吗?我应该将它们放入匿名名称空间吗?我从不在任何地方包含cpp文件 这是个好主意吗 是的,as#define有几个问题,例如: #define SIX 1 + 5 #define NINE 8 + 1 constexpr int the_answer = SIX * NINE; // 42 and not 54 我应该将它们放入匿名名称空

我总是使用
#define
在cpp文件开头的某个地方定义幻数。我想把它改成
const
numbers。(在cpp文件中声明/定义了globals。)这是个好主意吗?我应该将它们放入匿名名称空间吗?我从不在任何地方包含cpp文件

这是个好主意吗

是的,as
#define
有几个问题,例如:

#define SIX 1 + 5
#define NINE 8 + 1

constexpr int the_answer = SIX * NINE; // 42 and not 54
我应该将它们放入匿名名称空间吗

如果在文件范围内使用,是的,它是有意义的

这是个好主意吗

是的,as
#define
有几个问题,例如:

#define SIX 1 + 5
#define NINE 8 + 1

constexpr int the_answer = SIX * NINE; // 42 and not 54
我应该将它们放入匿名名称空间吗


如果在文件范围内使用,是的,它是有意义的。

基本上,选择这样的
#define
“consts”的唯一原因是预处理器本身是否需要使用它们。除此之外,
constepr
比使用这样的
#define
s有一大堆优势——它们是

只有在同一文件中使用幻数时,匿名名称空间才是一个好的解决方案,因为它内部的名称永远无法从其他翻译单元访问,因为就编译器而言,匿名名称空间具有唯一标识符。这就是说,将幻数放入匿名名称空间中并没有真正的好处,无论是
const
还是
constepr
变量在任何名称空间范围内

就对象上下文而言,
const
constepr
之间的区别而言,要点是,
constepr
表示编译期间已知的常量值,
const
仅表示常量值,这在编译过程中可能是未知的。1这种差异对于编译时编程或在其他应用程序中的使用至关重要


1请注意,作为其声明的一部分,本身使用常量表达式(如整数文字)初始化的
常量
整数,即使未显式声明
常量
,也隐式为常量表达式:

const int A = 50; // `A` is a constant expression

int n = 50;
const int B = n; // `B` is not a constant expression as it-
                 // is not being initialized with a constant expression

基本上,选择这样的
#define
“consts”的唯一原因是预处理器本身是否需要使用它们。除此之外,
constepr
比使用这样的
#define
s有一大堆优势——它们是

只有在同一文件中使用幻数时,匿名名称空间才是一个好的解决方案,因为它内部的名称永远无法从其他翻译单元访问,因为就编译器而言,匿名名称空间具有唯一标识符。这就是说,将幻数放入匿名名称空间中并没有真正的好处,无论是
const
还是
constepr
变量在任何名称空间范围内

就对象上下文而言,
const
constepr
之间的区别而言,要点是,
constepr
表示编译期间已知的常量值,
const
仅表示常量值,这在编译过程中可能是未知的。1这种差异对于编译时编程或在其他应用程序中的使用至关重要


1请注意,作为其声明的一部分,本身使用常量表达式(如整数文字)初始化的
常量
整数,即使未显式声明
常量
,也隐式为常量表达式:

const int A = 50; // `A` is a constant expression

int n = 50;
const int B = n; // `B` is not a constant expression as it-
                 // is not being initialized with a constant expression

constexpr
优于
#define
,如果在文件范围内使用,可以将它们放在未命名的命名空间中。不要忘记使它们不全是大写的。@换行符它们是大写的,因为它们是预处理器宏,而不是因为它们是常量。使用带有大写符号的编译时常量实际上会增加问题的风险,最初引入该模式是为了避免与预处理器的名称冲突。但是坏习惯是顽固的让它们保持静态或将它们放在匿名名称空间中没有意义,名称空间范围内的常量变量在默认情况下具有内部链接(即
静态
。@Newline
constepr
优于
#define
,如果在文件作用域中使用,您可以将它们放在未命名的命名空间中。不要忘记使它们不都是大写的。@换行符它们是大写的,因为它们是预处理器宏,而不是常量。使用带有大写符号的编译时常量实际上会增加问题的风险,最初引入该模式是为了避免与预处理器的名称冲突。但是坏习惯是顽固的使它们保持静态或将它们放在匿名名称空间中是没有意义的,名称空间范围内的常量变量在默认情况下具有内部链接(即
静态
是隐含的)。@Newline
6*9==42
在base 13中。“如果在文件范围内使用,是的,这是有意义的。”为什么?您的
答案已具有内部链接,因此无法在翻译单元之外访问。匿名名称空间有什么优势?@JonathanWakely:OP谈到了
const
,而不仅仅是
constexpr
。但确实不需要。我倾向于将所有文件范围的东西(变量/函数/类)放在未命名的名称空间中。
6*9==42
在base 13中。“如果在文件范围中使用,是的,它是有意义的。”为什么?您的
答案已具有内部链接,因此无法在翻译单元之外访问。匿名名称空间有什么优势?@JonathanWakely:OP谈到了
const
,而不仅仅是
constexpr
。但确实不需要。我倾向于将所有文件范围的内容(变量/函数/类)放在未命名的命名空间中。constexpr与const有区别吗?请注意,某些“fastbuild”编译工具会将所有C文件放在一起,并且匿名命名空间可能不像您想象的那样唯一