5

我有一个只有标题的项目。在里面我有一堂课。在它里面(或者实际上其他任何地方)我想要有常量数据(枚举值到字符串,反之亦然)。这个问题似乎比我预期的要困难得多。

typedef boost::bimap<MyEnum,std::string> Data;

我尝试过但没有奏效的方法:

  1. static Data const s_data = _initData();: 错误是这样的:only static const integral data members can be initialized within a class

  2. static Data const * const s_pData = _initData();:该_initData()函数有一个静态局部变量(在第一次调用时填充),并返回它的地址。没有与上述相同的原因。

我尝试过并且工作过,但我认为它很难看:

class Ugly {
public:
    static MyEnum lookupByName(std::string s)
    {
        MyEnum ret;
        lookup(ret,s,true);
        return ret;
    }
    static String lookupByEnum(MyEnum e)
    {
        std::string ret;
        lookup(e,ret,false);
        return ret;
    }
    static void lookup(MyEnum &e, std::string &s, bool etos)
    {
        static Data s_data = _fill();
        if(etos)
            s = /* ... */;
        else
            e = /* ... */;
    }
    static Data _fill(){ /* ... */ };
};

想法?

4

1 回答 1

8

更简单的是

static T& global_t()
{ static T z = initializer; return z; }

global_t()可用于需要 T 值的地方。

注意:在回答 rioki 评论时,我们还必须将函数指定为inline全局或命名空间级别(以避免链接器出现“多实例”问题)。

如果函数是模板或类成员函数(默认情况下内联定义),则不需要 inline 关键字

如果static T必须在不同的 OS 模块(读取:DLL)之间共享实例化,rioki 是完全正确的,但是 - 在这一点上 - 只有头文件的库不再有意义。


从 C++17 开始,说明inline符也可以用于变量。

所以,从 C++17 开始,你可以写

inline T global_object = initializer;

您还可以将 inline 用于函数的静态成员,以提供内联初始化,例如

class Class
{
    static inline Type static_object_name = initializer;
};
于 2013-03-08T12:52:42.130 回答