C ++:仅标头项目,静态const非整数 [英] C++: Header-only project, static const non-integral

查看:36
本文介绍了C ++:仅标头项目,静态const非整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个仅标头项目.在里面,我有一堂课.在里面(或其他实际位置),我想拥有恒定的数据(字符串的枚举值,反之亦然).这个问题似乎比我预期的要难得多.

  typedef boost :: bimap< MyEnum,std :: string>数据; 

我尝试了什么但没起作用:

  1. 静态数据const s_data = _initData(); :错误类似: 仅静态const整数数据成员可以在类中初始化 .

  2. 静态数据const * const s_pData = _initData(); : _initData()函数具有静态局部变量(在首次调用时填充),并返回了它的地址.出于上述原因无法正常工作.

我尝试和工作过的东西,但我认为它很丑:

  class丑陋{上市:静态MyEnum lookupByName(std :: string s){MyEnum ret;查找(ret,s,true);返回ret}静态字符串lookupByEnum(MyEnum e){std :: string ret;查找(e,ret,false);返回ret}静态空查找(MyEnum& e,std :: string& s,bool etos){静态数据s_data = _fill();如果(etos)s =/* ... */;别的e =/* ... */;}静态数据_fill(){/* ... */};}; 

想法?

解决方案

更简单的是

 静态T&global_t(){static T z =初始值设定项;返回z;} 

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

注意:为了回答rioki注释,如果函数在全局或命名空间级别,我们还必须将函数指定为 inline (以避免链接程序出现多个实例"问题).

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

如果必须在不同的OS模块(读取的是DLL)之间共享 static T 实例化,那么rioki是完全正确的,但是-在这一点上,仅使用标头的库就没有意义了.


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

因此,从C ++ 17开始,您只需编写

  inline T global_object =初始值设定项; 

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

  class类{静态内联类型static_object_name =初始值设定项;}; 

I have a header-only project. Inside it I have a class. Inside it (or anywhere else actually) I would like to have constant data (enum values to string and vice-verse). This problem seems a lot harder that I expected.

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

What I tried and did not work:

  1. static Data const s_data = _initData();: Error is like: only static const integral data members can be initialized within a class.

  2. static Data const * const s_pData = _initData();: The _initData() function had a static local variable (which became filled on first call), and returned the address of it. Did not work with the same reason as above.

What I tried and worked, but I consider it ugly:

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(){ /* ... */ };
};

Ideas?

解决方案

The simpler is

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

global_t() can be used whereve a T value is required.

NOTE: In answer to rioki comment, we must also specify the function as inline if it is at global or namespace level (to avoid the "multiple instances" problem towards the linker).

The inline keyword is not necessary if the function is a template or is a class member-function (for which the inline definition is by default)

If the static T instantiation must be shared among different OS modules (read: DLLs) rioki is perfectly right, but -at that point- a header-only library makes no more sense.


Starting from C++17, the inline specifier can also be used on variables.

So, from C++17 onward, you can just write

inline T global_object = initializer;

You can also use inline for static members of function, to provide inline initialization, like

class Class
{
    static inline Type static_object_name = initializer;
};

这篇关于C ++:仅标头项目,静态const非整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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