static constexpr int和old-fashioned枚举:什么时候为什么? [英] Static constexpr int vs old-fashioned enum: when and why?

查看:345
本文介绍了static constexpr int和old-fashioned枚举:什么时候为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是一个基本问题,但我现在无法看到自己的回应。



请考虑以下代码:

 模板< 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屋!

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