static constexpr int和old-fashioned枚举:什么时候为什么? [英] Static constexpr int vs old-fashioned enum: when and why?
问题描述
这可能是一个基本问题,但我现在无法看到自己的回应。
请考虑以下代码:
模板< bool b>
struct T {
static constexpr int value =(b?42:0);
};
template< bool b>
struct U {
enum {value =(b?42:0)};
};
int main(){
static_assert(T< true> :: value == 42,!
static_assert(T< false> :: value == 0,!);
static_assert(U< true> :: value == 42,!);
static_assert(U< false> :: value == 0,!);
}
我习惯于使用 T
,但不止一次,我看到像 U
的结构用于相同的目的(主要是traits定义)。
据我所见,它们都是在编译时解决的,他们解决了几乎相同的问题,但在我看来, T
是远比 U
(我知道,我个人的意见)。
我的问题很简单:是否有任何技术原因,其中一个解决方案比另一个更好?
更多,是否有任何情况下,其中一个是不可行的解决方案?
但是,<$ c>
$ c> enum 实际上更好,因为它是一个真正的命名常量。 constexpr
整型常数是一个对象,可以是,例如,使用ODR,并将导致链接错误。 #include< iostream>
struct T {
static constexpr int i = 42;
enum:int {x = 42};
};
void check(const int& z){
std :: cout< 检查:< z < \\\
;
}
int main(){
// check(T :: i); //取消注释这将导致链接错误
check(T :: x); $ 检查(T :: i) code>未注释,程序无法链接:
/tmp/ccZoETx7.o
:在函数` main
': ccc.cpp
:( .text + 0x45
):undefined
引用` T :: i ' collect2
:错误: ld
返回 1
退出状态
但是,真正的枚举
总是起作用。
This is maybe a basic question, but I cannot see the response by myself right now.
Consider the following code:
template<bool b>
struct T {
static constexpr int value = (b ? 42 : 0);
};
template<bool b>
struct U {
enum { value = (b ? 42 : 0) };
};
int main() {
static_assert(T<true>::value == 42, "!");
static_assert(T<false>::value == 0, "!");
static_assert(U<true>::value == 42, "!");
static_assert(U<false>::value == 0, "!");
}
I'm used to using structs like T
, but more than once I've seen structs like U
used for the same purpose (mostly traits definition).
As far as I can see, they are both resolved at compile time and they solve almost the same problem, but it seems to me that T
is far more readable than U
(well, I know, my personal opinion).
My question is pretty simple: is there any technical reason for which one solution is better than the other one?
Even more, is there any case for which one of them is not a viable solution?
解决方案 There will be no noticeable difference for integral constants when used like this.
However, enum
is actually better, because it is a true named constant. constexpr
integral constant is an object which can be, for example, ODR-used - and that would result in linking errors.
#include <iostream>
struct T {
static constexpr int i = 42;
enum : int {x = 42};
};
void check(const int& z) {
std::cout << "Check: " << z << "\n";
}
int main() {
// check(T::i); // Uncommenting this will lead to link error
check(T::x);
}
When check(T::i)
is uncommented, the program can not be linked:
/tmp/ccZoETx7.o
: In function `main
': ccc.cpp
:(.text+0x45
): undefined
reference to `T::i
' collect2
: error: ld
returned 1
exit status
However, the true enum
always works.
这篇关于static constexpr int和old-fashioned枚举:什么时候为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!