C++枚举转底层类型仍不匹配函数签名的问题
我定义了如下函数:
void get_u16(const char *const key, uint16_t &output) { ...stuff goes here }
以及如下枚举类型:
struct MyEnum { typedef enum : uint16_t { FOO = 0, BAR = 1, } Type; };
尝试通过以下方式调用函数:
MyEnum::Type thingy = MyEnum::BAR; get_u16("some key", (uint16_t)thingy);
但出现编译错误:
/project/components/Data/Data.cpp:498:77: error: cannot bind non-const lvalue reference of type 'uint16_t&' {aka 'short unsigned int&'} to an rvalue of type 'uint16_t' {aka 'short unsigned int'}
该枚举的底层类型为uint16_t,我也已在调用时进行了强制转换,但仍不匹配函数签名。请问如何让C++将其视为uint16_t以满足调用要求?
编译报错的核心原因是:强制类型转换(uint16_t)thingy会生成一个临时的右值,而函数get_u16的第二个参数要求的是非const左值引用,C++不允许将右值绑定到非const左值引用上。以下是几种可行的解决方法:
方法1:借助临时变量传递
创建一个uint16_t类型的临时变量,将枚举值赋值给它后再传入函数。由于枚举的底层类型就是uint16_t,这里可以直接隐式转换:
MyEnum::Type thingy = MyEnum::BAR; uint16_t temp = thingy; get_u16("some key", temp); // 若需要同步修改后的结果,可再写回枚举变量 thingy = static_cast<MyEnum::Type>(temp);
方法2:修改函数参数为const引用(逻辑允许时)
如果函数get_u16不需要修改传入的output参数,或者当前调用场景无需修改原变量,可以将函数签名改为接受const uint16_t&:
void get_u16(const char *const key, const uint16_t &output) { ...stuff goes here }
此时临时转换结果(右值)可以绑定到const左值引用上,原调用代码无需改动。
方法3:强制转换为左值引用(不推荐)
若不想额外创建变量,可通过static_cast将枚举变量直接转换为uint16_t&,再配合std::ref传递,但这种写法不够直观,且需确保枚举底层类型确实是uint16_t,否则可能引发未定义行为:
#include <functional> MyEnum::Type thingy = MyEnum::BAR; get_u16("some key", std::ref(static_cast<uint16_t&>(thingy)));
内容的提问来源于stack exchange,提问作者chrispitzer

