#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. Согласен. Там мне нужно было «Почти вернуться к старым временам».