Передача переменной Количество аргументов с другим типом - С++

Я кодирую на С++ и имею несколько вопросов относительно многоточия:

  • Можно ли передать указатель класса или класса в многоточие?

  • В основном я хочу передать переменное количество аргументов в типе 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 такое соглашение определяется строкой формата. Вам необходимо определить такой "протокол связи", который позволяет использовать список переменных аргументов. Конечно, это не безопасно.