C++ struct内定义CoreAudio静态常量遇编译链接错误如何解决?
问题原因
- 第一个报错
invalid use of non-static data member 'mute':非静态数据成员属于struct的实例对象,不属于类本身,不能直接通过类名::成员名的方式访问,必须先创建struct实例才能访问。 - 第二个要求加
constexpr的报错:C++标准规定,只有整型、枚举类型的静态const成员支持类内直接初始化,其他自定义类型的静态const成员类内初始化必须使用constexpr修饰。 - 最后的链接错误:C17之前的标准中,
static constexpr类成员虽然可以类内初始化,但如果被odr-used(比如作为函数参数传递、取地址、绑定引用等场景),必须在类外额外提供一次定义,否则链接器无法找到对应的符号。C17及之后版本中static constexpr类成员默认是隐式inline的,不需要额外类外定义。
可行解决方案
方案1:升级编译标准到C++17及以上
编译时指定C++17或更高标准(比如编译参数加-std=c++17),原有static constexpr的写法无需修改即可正常运行。
方案2:C++11/14环境下补充类外定义
在类内保留static constexpr声明的前提下,在对应的实现文件(.cpp)中补充成员的定义:
// .h头文件中的struct定义 struct properties { static constexpr AudioObjectPropertyAddress volume = { kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, 0 }; static constexpr AudioObjectPropertyAddress mute = { kAudioDevicePropertyMute, kAudioDevicePropertyScopeOutput, 0 }; }; // .cpp实现文件中补充定义 constexpr AudioObjectPropertyAddress properties::volume; constexpr AudioObjectPropertyAddress properties::mute;
方案3:使用静态常量函数兼容所有C++11+环境
这种方式无需额外定义,也不受编译版本限制:
struct properties { static constexpr AudioObjectPropertyAddress get_volume() { return {kAudioDevicePropertyVolumeScalar, kAudioDevicePropertyScopeOutput, 0}; } static constexpr AudioObjectPropertyAddress get_mute() { return {kAudioDevicePropertyMute, kAudioDevicePropertyScopeOutput, 0}; } }; // 调用方式 setProperty(1, properties::get_mute());
内容的提问来源于stack exchange,提问作者br0kenpixel
相关产品推荐
相关产品推荐

