Объявление функции с переменным числом аргументов VS функция, принимающая список

При разработке класса или функции, какой из способов, показанных ниже, лучше и почему?

class Container {

    //Provide this functionality??
    void addItemVariadic(const Value& val, ...);

    //Or provide this functionality??
    void addItemList(const list<Value>& vals);

};

Что лучше - предоставить такую ​​функцию, как addItemVariadic (..) или addItemList (..)?

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


person phoad    schedule 18.01.2013    source источник
comment
Есть и другие варианты - вы можете написать функцию, которая принимает итераторы в качестве входных данных, так она будет работать со всеми контейнерами stl. Синтаксис выглядит примерно так: template ‹typename InputIterator› void foo (начало InputIterator, конец InputIterator)   -  person aCuria    schedule 15.02.2013


Ответы (1)


Использование вариативных функций опасно

Если вы когда-либо передадите переменную, которая не имеет типа appriopriate, она выйдет из строя во время выполнения при вызове функции.

Напротив, если вы используете std::list, он не будет компилироваться просто, и вы избежите сбоя.

Кстати: я советую вам использовать std::vector вместо std::list в этом случае.

Edit1 Возможное дублирование Вопрос. с хорошим решением, использующим оператор ‹< для ввода всех параметров за один раз.

Edit2. Чтобы выбирать между различными контейнерами std ::, существует диаграмма выбора в качестве ответа на этот вопрос. Этот график относится к C ++ 03, он не охватывает новые контейнеры, представленные в C ++ 1.

person Stephane Rolland    schedule 18.01.2013
comment
Что лучше: добавлять элементы по одному или предоставлять возможность добавлять их за один снимок? Почему использование std :: vector может быть полезным из-за меньших накладных расходов на указатели? - person phoad; 18.01.2013
comment
правило состоит в том, что std :: vector выполняет работу с контейнерами в 95-99% случаев. Мы должны использовать std :: deque, std :: list, std :: forward_list, только если мы знаем почему: я свяжу вас с графом, который поможет выбрать это. Чтобы добавить все переменные в один снимок, нужна вариативная функция ;-). - person Stephane Rolland; 18.01.2013
comment
Я имею в виду вызов addItem () один раз для каждого элемента или вызов с предоставлением ему вектора. - person phoad; 18.01.2013
comment
@phoad Если вы называете это предоставлением вектора, вы просите внешний мир вашего бизнес-класса / функции выполнить работу по построению вектора и добавлению элементов. Напротив, если вы используете addItem, эта работа удаляется во внутреннюю часть addItem. Это зависит от того, сколько раз в вашем коде вызывается ваша функция. Если несколько раз, то у вас повсюду распространен весь стандартный код построения вектора. (просто чтобы дать вам подсказку). это ваш выбор после и ваш вкус :-) - person Stephane Rolland; 18.01.2013
comment
@phoad Я отредактировал свой ответ и дал вам ссылку на человека, который задавал точно такой же вопрос. Там есть хорошее решение, используя оператор ‹<, чтобы объединить все входные данные за один раз. Вероятно, проще в использовании, чем решение std :: vector. - person Stephane Rolland; 18.01.2013
comment
@phoad, а в Edit2 - ссылка на вопрос, есть ли график для выбора между контейнерами. - person Stephane Rolland; 18.01.2013