2017-06-27 41 views
-2

我有一个类表示一个值,并且可以假定单个数值,单个字符串,一个数组值或一个键映射值对。传递一个常量文字数组而不声明它是一个变量

这里是currrent定义:

class Foo { 
public: 
    typedef enum { STRING, NUMBER, ARRAY, MAP } data_type; 
    struct str_less { 
     bool operator()(const char *a, const char *b) const { 
      return strcmp(a,b)<0; 
     } 
    }; 
    inline Foo(int n):type(NUMBER),number_value(n) { } 
    inline Foo(double n):type(NUMBER),number_value(n) { } 
    inline Foo(const char *s):type(STRING),string_value(s) { } 
    inline Foo(const std::initializer_list<std::pair<const char *const,Foo>> &arg):type(MAP),map_value(arg) { }  
    template<size_t N> inline Foo(const Foo (&arg)[N]):type(ARRAY) { std::copy(&arg[0], &arg[N], std::back_inserter(arg)); } 
    inline Foo(const std::vector<Foo> &arg):type(ARRAY),array_value(arg) { } 
private: 
    data_type type; 
    double number_value = 0; 
    const char *string_value = ""; 
    std::vector<Foo> array_value; 
    std::map<const char *,Foo, str_less> map_value; 
}; 

我只从实例在编译时给定的......我的目的,这个值过班感兴趣,其将绝不会在运行时使用变量称为作为论据。

由于Foo构造函数的,在编译时指定的任何文字值会得到自动型转换成Foo,然后我可以指定在一个几乎JSON状方式文字如:

Foo({ 
    {"number_key", 100}, 
    {"array_key", std::vector<Foo> 
     {1, 3, 4, 
      { 
       {"inner_key", "value"}, 
       {"second_key", 500}}, "abc"}}}); 

但是,正如你所看到的那样,我需要对std :: vector进行明确的转换来支持数组类型。在C++ 11中有没有办法将某种类型的文字数组传递给一个函数,以便我可以适当地调用template<size_t N> Foo::Foo(const Foo (&arg)[N])?我非常喜欢这一点,因为要求显式向量转换感觉很尴尬,并且绝对不会与其他自动转换类型的构造函数不同。我想知道是否有其他方式可以利用智能自动类型转换以更统一简洁的方式进行操作?

我以前见过这样的代码:

template<std::size_t N> void do_stuff(const char (&str)[N]) ... 

可与字符串文字被调用,所以在概念机制似乎理解编译时文字排列存在,但有什么办法可以指定一个常量数组类型其他char

+0

发布一些编译代码,说明你是问什么。 –

+0

我修改了帖子来澄清我的问题,并确保此次编译代码片段。 – markt1964

回答

1

像这样的东西应该工作:

template <typename... Args> 
Foo(Args&&... args) : 
    array_value{Foo(std::forward<Args>(args))...} 
{} 

Foo foo(4.2, "hello"); 

Proof of concept

+0

这适用于您描述的情况,但只要添加initializer_list方法并尝试添加地图,就会失败。 http://rextester.com/ZDGZ73427 – markt1964

+0

它可以打捞成'Foo foo(4.2,“hello”,Foo {{“w”,100}});'这是可以做的最好的,我怀疑;一个模板参数永远不能从brace-init列表中推导出来。 –

相关问题