Передача константного литерального массива в функцию без объявления его как переменной

У меня есть класс, который представляет значение и может принимать либо значение из одного числа, одной строки, массива значений или карту пар ключей-значений.

Вот текущее определение:

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?

-2

Решение

Примерно так должно работать:

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

Foo foo(4.2, "hello");

Доказательство концепции

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]