有没有一种优雅的方式来表示包含C ++中不同类型的地图? [英] Is there an elegant way to represent a map containing different types in C++?

查看:187
本文介绍了有没有一种优雅的方式来表示包含C ++中不同类型的地图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个类,我想使用以下各种参数配置: int double string (或 const char * )。在像Ruby这样的语言中,我将构建一个初始化函数,该函数接受由字符串键入的散列。例如:

I'm building a class which I want to configure using various parameters which may one of: int, double and string (or const char * for that matter). In a language like Ruby, I would build an initialization function that takes a hash keyed by a string. For example:

class Example
  def init_with_params params
    puts params
  end
end

e = Example.new
e.init_with_params({ "OutputFile" => "/tmp/out.txt", "CaptureFPS" => 25.0, "RetryDelaySeconds" => 5 })

如何在C ++中创建类似的行为?

How can I create a similar behavior in C++?

看看我发现了几个帖子谈论 boost :: variant 。我想避免使用boost如果通过限制不同的类型到上面提到的3种类型,可以做一个相当干净的解决方案。

Looking around I found several posts talking about boost::variant. I would rather avoid using boost if by limiting the different types to the 3 types I mentioned above a rather clean solution can be made.

编辑
我同意使用一个精心设计和广泛测试的代码,如Boost.Variant比重新实现相同的想法好得多。在这种情况下,问题减少到只使用3种基本类型,所以我一直在寻找实现它的最简单的可能方法。

Edit: I agree that using a well designed and widely tested code such as Boost.Variant is much better than re-implementing the same idea. In this case, the problem is reduced to using only 3 basic types, so I was looking for the simplest possible way of implementing it.

推荐答案

这是我经常用来存储程序配置属性的一个缩减版本,也许你会发现它有用: / p>

Here is a cut down version of something I regularly use to store program configuration properties, maybe you will find it useful:

#include <map>
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
#include <initializer_list>

class config
{
    // everything is stored internally as std::strings
    // usually read from a configuration file
    typedef std::map<std::string, std::string> prop_map;
    typedef prop_map::const_iterator prop_map_citer;

    prop_map props;

public:
    // example constructor. Normally I have a method to read the
    // values in from a file
    config(std::initializer_list<std::pair<std::string, std::string>> list)
    {
        for(const auto& p: list)
            props[p.first] = p.second;
    }

    // values are converted as they are requested to whatever types
    // they need to be. Also a default may be given in case the value
    // was missing from the configuration file
    template<typename T>
    T get(const std::string& s, const T& dflt = T()) const
    {
        prop_map_citer found = props.find(s);

        if(found == props.end())
            return dflt;

        T t;
        std::istringstream(found->second) >> std::boolalpha >> t;
        return t;
    }

    // std::strings need special handling (no conversion)
    std::string get(const std::string& s, const std::string& dflt = "") const
    {
        prop_map_citer found = props.find(s);
        return found != props.end() ? found->second : dflt;
    }

};

int main()
{
    const config cfg =
    {
        {"OutputFile", "/tmp/out.txt"}
        , {"CaptureFPS", "25.0"}
        , {"RetryDelaySeconds", "5"}
    };

    std::string s;
    float f;
    int i;

    s = cfg.get("OutputFile");
    f = cfg.get<float>("CaptureFPS");
    i = cfg.get<int>("RetryDelaySeconds");

    std::cout << "s: " << s << '\n';
    std::cout << "f: " << f << '\n';
    std::cout << "i: " << i << '\n';
}

这篇关于有没有一种优雅的方式来表示包含C ++中不同类型的地图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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