Передача переменной Количество аргументов с другим типом - С++
Я кодирую на С++ и имею несколько вопросов относительно многоточия:
-
Можно ли передать указатель класса или класса в многоточие?
-
В основном я хочу передать переменное количество аргументов в типе char*
и class
. В настоящее время я использую многоточие и пытаюсь понять, как пройти в классе. Если эллипсис здесь не применим, какие варианты доступны?
Я хочу, чтобы пользователь напрямую вызывал функцию с помощью func( params 1, params2, ...)
без явного назначения параметров в вектор или массив сначала перед передачей вектора или массива в качестве аргумента функции.
Ответы
Ответ 1
Вы должны учитывать, что использование вариационных функций (C-style) является опасным недостатком.
Если объекты, переданные функции, не соответствуют ожидаемому типу, или если вы не указали точное количество ожидаемых параметров, тогда вы в основном имеете сильную краху во время выполнения.
В Bjarne Stroustrup С++ In Depth Series - Стандарты кодирования С++ - 101 Правила, рекомендации и рекомендации по Herb Sutter и Andrei Alexandrescu, глава 98: Не используйте varargs (многоточие)
Я глубоко подписался на предложение @tenfour:
- используйте
std::vector
, который содержит все ваши параметры.
Ответ 2
Вы можете передавать все, что хотите, для вариационных функций, но это не поможет вам писать удобные функции, поскольку вы теряете информацию о типе для аргументов.
В зависимости от того, что вы хотите достичь, есть лучшие альтернативы:
-
операторы цепочки, такие как <<
или ()
:
helper() << a << b << c;
helper(a)(b)(c);
-
с использованием (псевдо) вариационных шаблонов:
template<class T0> void func(T0 t0) { ... }
template<class T0, class T1> void func(T0 t0, T1 t1) { ... }
// ...
// or if you can use C++0x features:
template<class... Args> void func(Args... args) { ... }
- ... больше?
Ответ 3
Вы можете передать указатель класса с varargs, да. Но функция, получающая указатель, должна знать, что с ней делать. Это должно будет привести его к чему-то полезному. Вот почему printf() позволяет указать тип аргумента в спецификаторе формата.
Один из вариантов - передать список функции, например std::vector
.
[edit] Возможно, вы захотите сделать что-то, чтобы сделать синтаксис короче, поэтому вы можете передать свои аргументы следующим образом:
foo(blah, StartAList(a)(b)(c)(d));
или stream-ish:
foo(blah) >> a >> b >> c >> d;
или путем перегрузки:
void foo(T a) { ... }
void foo(T a, T b) { ... }
void foo(T a, T b, T c) { ... }
Ответ 4
Используя вариативные шаблоны С++ 0x, вы можете упаковать все свои аргументы в кортеж и использовать код, который я разместил в потоке ниже, чтобы распаковать их в вызов функции (статическая функция или функция объекта).
Как расширить кортеж в аргументы функции вариационной матрицы?
Ответ 5
Возможны истинные типы переменных аргументов с новыми аргументами шаблона переменной переменной в С++ 0x
Вы также можете получить с помощью boost:: any
Ответ 6
Если экземпляр класса (или указатель) используется всегда, лучше использовать фиксированный параметр, который передается перед списком переменных параметров, например format в printf. Что касается... параметров, они могут иметь любой тип (включая экземпляр класса или указатель), а их количество и типы зависят от какого-либо соглашения между вызывающей и вызываемой функциями. Например, для printf такое соглашение определяется строкой формата. Вам необходимо определить такой "протокол связи", который позволяет использовать список переменных аргументов. Конечно, это не безопасно.