Необходимость передавать разные типы в initialization_list

#c #templates #variadic-templates

#c #шаблоны #переменные-шаблоны

Вопрос:

Я ищу основанный на шаблоне способ передачи произвольного количества параметров в initialization_list (ах).

Что-то вроде:

 func({0, 1}, {0, 2.0f}, {0, "boo"}, ...);
  

или

 func({{0, 1}, {0, 2.0f}, {0, "boo", ...}});
  

В то же время я хочу иметь возможность проверять тип второго параметра в каждой (внутренней) фигурной скобке. Может быть, получить sizeof(T) , может быть, сделать какое if constexpr(std::is_same<T, ...>::value) -то совпадение.

Возможно ли это? Если да, то как будет func() выглядеть определение?

Комментарии:

1. Во внутренних фигурных скобках всегда есть 2 элемента?

2. std::initializer_list<T> где T находится тип с перегруженными конструкторами?

3. @cigien да, в основном индекс и значение

4. Определить типы не обязательно сложно. Что вы хотите делать со всеми этими типами внутри func ?

5. Мой план состоит в том, чтобы скопировать память, занятую переменными произвольных типов, в какую-нибудь непрозрачную область памяти. Информация о типе необходима для получения sizeof(T) для передачи размера в memcpy.

Ответ №1:

Заставить f взять std::initializer_list<std::pair<std::any, std::any> > :

 void f(std::initializer_list<std::pair<std::any, std::any> > il) {
    for (auto it = il.begin(); it != il.end();   it) {
        const std::type_infoamp; type1 = it->first.type();
        const std::type_infoamp; type2 = it->second.type();
        if (type1 == typeid(int)) {
            int val1 = std::any_cast<int>(it->first);
        }
        // ...
    }
}
  

Если у вас есть только пара возможных типов, вы можете использовать std::variant<int, float, /*e.g.; etc. */> вместо std::any .

Комментарии:

1. Variant вероятно, это лучший вариант. Когда у вас есть функция, которая может потреблять абсолютно произвольное количество абсолютно произвольных типов, у вас, вероятно, проблема с дизайном. Что бы ни находилось на серверной части, использующей все эти аргументы, будет сложным и уязвимым для неверных входных данных. Вернемся к старым временам varargs функций.

2. @user4581301 За исключением того, что std::any выдает исключение, если вы пытаетесь получить к нему доступ с неправильным типом, поэтому объекты внутри могут быть скопированы максимум, если их типы не обрабатываются явно. Не похоже на функции varargs.

3. Согласен. Там мне нужно было «Почти вернуться к старым временам».