2013-02-22 3 views
1

Я ищу ответы, но я не могу найти соответствующую информацию по этому вопросу. Давайте рассмотрим пример:Список аргументов переменных C++

class MyClass 
{ 
    //member functions and variables 
}; 

void foo(int pivot,...) 
{ 
    va_list arguments; 
    va_start(arguments,pivot); 

    //va_arg(arguments,???) 

    va_end(arguments); 
} 

void bar() 
{ 
    MyClass a; 
    MyClass * b = &a; 
    const MyClass & c = a; 
    foo(0,a,b,c); 
} 

Как аргументы a, b и c прошло? По значению или по ссылке и как их запрашивать с помощью va_arg? Как насчет конструкторов/деструкторов для MyClass? Где в стандарте C++ указан такой тип поведения?

+0

примеры для 'va_arg': http://en.cppreference.com/w/cpp/utility/variadic/va_arg –

+0

вариативные функции: http://en.cppreference.com/w/cpp/utility/variadic и variadic templates from C++ 11: http://www.cplusplus.com/articles/EhvU7k9E/ – CCJ

+0

Вы не можете передавать объекты с определенными пользователем конструкторами. –

ответ

5

Вы не должны использовать пользовательские типы в функции var-arg. Используйте C++ 11 вариационных шаблонов.

Если ваш класс не стручок типа - это не определен стандартом, благодаря Vaughn Катону для замечания

n3337 5.2.2/7

пропускания потенциально оцененной аргумент типа класса (пункт 9), имеющий нетривиальный конструктор копирования , нетривиальный конструктор перемещения или нетривиальный деструктор, без соответствующего параметра , условно поддерживается семантикой, определенной реализацией.

Else, вы можете, и это будет правильно, но вы не будете.

+0

Тогда должно быть безопасно использовать MyClass * только в случае необходимости. Я тестировал этот msvc, и он кажется законным. – Raxvan

+1

И, конечно же, он недостаточно показывает нам, что «MyClass» не является POD. Хотя традиционно классы POD определяются ключевым словом 'struct', что-то вроде' class MyClass {public: int a; int b; }; 'является совершенно законным и является POD. –

3

По значению. Но будьте осторожны, если MyClass не является POD, программа имеет неопределенное поведение (C++ 03, §5.2.2/7), или если MyClass имеет нетривиальный конструктор копирования, переместите конструктор или деструктор, операцию условно поддерживается, с реализацией определена семантика (C++ 11, §5.2.2/7).

В вашем примере, проходя a и проходя c ровно идентичные операции (за исключение того, что c не может быть связана с неконстантной ссылкой, но это не проблема здесь, поскольку переменных аргументов все проходят по значению). Таким образом, при звонке foo вы отправите номер 0, копию a, копию указателя b и копию из a. Чтобы получить к ним доступ в foo, вам необходимо объявить в va_arg как int, MyClass, MyClass* и MyClass.

Смежные вопросы