2015-08-14 3 views
1

У меня есть класс, который содержит вектор определенного типа, и я хочу дать ему вариационный конструктор, который добавляет элементы к вектору.Как остановить проверку вариационных аргументов

class MyClass 
{ 
    std::vector<int> numbers; 
    MyClass(int &x...) 
    { 
     va_list args; 
     va_start(args, x); 
     while(/*some condition, I'm not sure*/) 
     { 
      numbers.push_back(va_arg(args, int)); 
     } 
     va_end(args); 
    } 
}; 

Как узнать, когда прекратить проверку аргументов? Является ли мой вариационный синтаксис даже правильным? Все, что мне нужно было сделать, это учебник по вариационным функциям на cppreference.com.

+3

Простой ответ: вы не можете знать. Вот почему у вас должна быть схема какого-то определения последнего элемента. Либо значением дозорного, либо другим параметром, который сообщает вам количество аргументов, либо использует метод, который использует 'printf', и это строка формата описывает параметры, которые нужно искать. – PaulMcKenzie

+0

Возможно, что-то вроде: 'MyClass (int num_of_args, int & ...)'? –

+0

@RemyLebeau Я даже не думаю, что вы можете иметь ссылочный аргумент как параметр перед '...'. – PaulMcKenzie

ответ

4

Вы не можете использовать списки аргументов переменной C-стиля, если вы как-то не сообщите функции, сколько аргументов она получает. Например, вы можете передать int count в качестве первого аргумента в список аргументов переменных и использовать этот счетчик, чтобы определить, когда прекратить обработку аргументов. Такие функции, как printf(), используют строку формата, чтобы определить, сколько аргументов ожидать (и какой тип они получили).

Самый простой способ дать ваш класс переменное число аргументов, чтобы не использовать переменные списки аргументов, а скорее использовать std:initializer_list<int>:

#include <initializer_list> 
#include <vector> 

class MyClass { 
    std::vector<int> v; 
public: 
    MyClass(std::initializer_list<int> args): v(args) {} 
}; 

Он может быть использован, как это:

MyClass object1{ 1, 2, 3, 4 }; 
MyClass object2({ 1, 2, 3, 4 }); 

Если вы хотите использовать вариационный шаблон, обозначение для конструктора будет примерно таким:

template <typename... T> 
MyClass(T&&... args): v{ std::forward<T>(args)... } {} 

Однако это может сделать что-то по-разному. Я предлагаю пойти с std::initializer_list<int>.

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