简体   繁体   English

在结构中定义常量

[英]define constants in a struct

I'm trying to create a struct with some constants in it like this:我正在尝试创建一个包含一些常量的结构,如下所示:

#include <CoreAudio/CoreAudio.h>
...
struct properties {
    //Volume control
    const AudioObjectPropertyAddress volume = {
        kAudioDevicePropertyVolumeScalar, //mSelector
        kAudioDevicePropertyScopeOutput, //mScope
        0 //mElement
    };
    //Mute control
    const AudioObjectPropertyAddress mute = { 
        kAudioDevicePropertyMute,
        kAudioDevicePropertyScopeOutput,
        0
    };
};

However, I cannot access the constants in this class;但是,我无法访问这个 class 中的常量;

//Function used to for example set volume level or set mute status
//bool setProperty(UInt32 data_to_write, AudioObjectPropertyAddress addr_to_write_to);
//Following line should mute the system audio
setProperty(1, properties::mute);

This will make the compiler return the following error:这将使编译器返回以下错误:

error: invalid use of non-static data member 'mute'

So, I tried making the constants static like this:所以,我试着像这样制作常量 static:

const static AudioObjectPropertyAddress volume = { ...

But now, I get a different error:但是现在,我得到了一个不同的错误:

error: in-class initializer for static data member of type 'const AudioObjectPropertyAddress' requires 'constexpr' specifier

The last thing I tried is changing const static to static constexpr , however again, I cannot access the constants.我尝试的最后一件事是将const static更改为static constexpr ,但是同样,我无法访问常量。 Every time I try to access them, the compiler show this error:每次我尝试访问它们时,编译器都会显示此错误:

Undefined symbols for architecture x86_64:
  "properties::mute", referenced from:
      _main in main-fefb9f.o
ld: symbol(s) not found for architecture x86_64

I'm not really sure what's going on here, I tried converting my struct into a class, but I ended up getting the same Undefined symbols error.我不太确定这里发生了什么,我尝试将我的结构转换为 class,但我最终得到了相同的Undefined symbols错误。 I know I could just define the two constants as global variables, but I thought putting them into a struct/class would make the code look "nicer" or just more organized.我知道我可以将这两个常量定义为全局变量,但我认为将它们放入结构/类中会使代码看起来“更好”或更有条理。 Could someone please explain what's wrong here and provide a possible solution?有人可以解释这里出了什么问题并提供可能的解决方案吗?

why not just properties.volume and properties.mute or use namespace otherwise...为什么不只是 properties.volume 和 properties.mute 或者使用命名空间,否则......

namespace properties 
{
    //Volume control
    const AudioObjectPropertyAddress volume = {
        kAudioDevicePropertyVolumeScalar, //mSelector
        kAudioDevicePropertyScopeOutput, //mScope
        0 //mElement
    };

    //Mute control
    const AudioObjectPropertyAddress mute = { 
        kAudioDevicePropertyMute,
        kAudioDevicePropertyScopeOutput,
        0
    };
};
  •  struct properties { //Volume control const AudioObjectPropertyAddress volume = { kAudioDevicePropertyVolumeScalar, //mSelector kAudioDevicePropertyScopeOutput, //mScope 0 //mElement }; };

    is valid, but volume is not a static member, so usage requires an instance:有效,但volume不是 static 成员,因此使用需要一个实例:

     setProperty(1, properties{}.volume);
  • With static const , it would be:使用static const ,它将是:

     struct properties { //Volume control static const AudioObjectPropertyAddress volume; }; const properties::AudioObjectPropertyAddress volume { kAudioDevicePropertyVolumeScalar, //mSelector kAudioDevicePropertyScopeOutput, //mScope 0 //mElement };

    and usage might be the expected:并且用法可能是预期的:

     setProperty(1, properties::volume);
  • with static constexpr in C++11/C++14:在 C++11/C++14 中使用static constexpr

     struct properties { //Volume control static constexpr AudioObjectPropertyAddress volume{ kAudioDevicePropertyVolumeScalar, //mSelector kAudioDevicePropertyScopeOutput, //mScope 0 //mElement }; }; const properties::AudioObjectPropertyAddress volume; // Definition when ODR-used
  • with static /*inline*/ constexpr since C++17:自 C++17 以来,使用static /*inline*/ constexpr

     struct properties { //Volume control static /*inline*/ constexpr AudioObjectPropertyAddress volume{ kAudioDevicePropertyVolumeScalar, //mSelector kAudioDevicePropertyScopeOutput, //mScope 0 //mElement }; };

Here are a list of things you can try:以下是您可以尝试的事项列表:

You could.... redesign your templating/types.你可以......重新设计你的模板/类型。 Struct vs Namespace . 结构与命名空间 Without seeing the whole project its tough to guide in a specific direction.在没有看到整个项目的情况下,很难在特定方向上进行指导。 Its up to you to decide if you need to use a struct, enum, namespace, class to encapsulate your code.由您决定是否需要使用结构、枚举、命名空间、class 来封装您的代码。

As for const static declaration.至于 const static 声明。 Here is a post describing valid methods of static class membder declarations. 这是一篇描述 static class 成员声明的有效方法的帖子。 Pay close attention to your c++ version.请密切注意您的 c++ 版本。

"Prior to C++11, only static const data members of integral or enumeration type could have initializers in the class definition." “在 C++11 之前,只有 static 整型或枚举类型的 const 数据成员可以在 class 定义中具有初始值设定项。”

Lastly, the static constexpr undefined.最后,static constexpr 未定义。 Is your static var in the same header/source file as where you are calling it?您的 static var 是否在与您调用它的位置相同的头文件/源文件中? (Likely not, as the error shows the call from main). (可能不是,因为错误显示来自 main 的调用)。 Static variables are not visible to other files . Static 变量对其他文件不可见

If you want to modify static vars you could do so using a public get/set from a class function.如果你想修改 static 变量,你可以使用来自 class function 的公共获取/设置。

Suppose 'mute' is a single uint8_t value.假设“静音”是单个 uint8_t 值。 Consider using a namespace with all static data declared as: static const uint8_t mute.考虑使用一个命名空间,所有 static 数据声明为:static const uint8_t mute。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM