Рассмотрите класс X
с N
членские переменные, каждый некоторый copiable и подвижный тип, и N
соответствующие функции метода set. В C++ 98, определение X
вероятно, выглядел бы примерно так:
class X
{
public:
void set_a(A const& a) { _a = a; }
void set_b(B const& b) { _b = b; }
...
private:
A _a;
B _b;
...
};
Функции метода set класса X
выше может связать и с lvalue и с rvalue аргументами. В зависимости от действительного аргумента это могло бы привести к созданию временного файла и в конечном счете приведет к присвоению копии; из-за этого, non-copiable типы не поддерживаются этим дизайном.
С C++ 11 у нас есть семантика перемещения, идеальная передача и универсальные ссылки (терминология Scott Meyers), которые допускают более эффективное и обобщенное использование функций метода set путем перезаписи их этот путь:
class X
{
public:
template<typename T>
void set_a(T&& a) { _a = std::forward<T>(a); }
template<typename T>
void set_b(T&& b) { _b = std::forward<T>(b); }
...
private:
A _a;
B _b;
...
};
Универсальные ссылки могут связать с const
/non-const
, volatile
/non-volatile
, и к любому конвертируемому типу в целом, избегая создания временных файлов и передавая значения прямо operator =
. Non-copiable, подвижные типы теперь поддерживаются. Возможно нежелательная привязка может быть устранена любой через static_assert
или через std::enable_if
.
Таким образом, мой вопрос: как руководство по проектированию, должен все (скажем, большинство) функции метода set в C++ 11 быть записанным как шаблоны функций, принимающие универсальные ссылки?
Кроме более громоздкого синтаксиса и невозможности использования подобных Intellisense инструментов помощника, когда написание кода в тех функциях метода set, там какие-либо соответствующие недостатки с гипотетическим принципом "функции метода set записи как шаблоны функций, принимающие универсальные ссылки каждый раз, когда возможный"?