Использование decltype для написания функций копирования и перемещения

В моем коде есть пара случаев, когда функции реагируют лишь немного по-разному, когда сталкиваются с T&& или const T&однако сами функции довольно длинные (обратите внимание, что T — это просто некоторый тип объекта). Например:

void push_back(const T& newt){
/* code block X */
new (ptr) T(newt);
/* code block Y */
}

void push_back(T&& newt){
/* code block X */
new (ptr) T(std::move(newt));
/* code block Y */
}

Можно ли написать что-то вроде этого псевдокода:

template<typename S>
void push_back(S newt){
/* code block X */
#if decltype(newt)==T&&
new (ptr) T(std::move(newt));
#else
new (ptr) T(newt);
#endif
/* code block Y */
}

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

2

Решение

использование std::forward() в T&& функционировать и отказаться от const T& функция:

template <typename T>
void push_back(T&& newt){
/* code block X */
new (ptr) typename std::remove_reference<T>::type(std::forward<T>(newt));
/* code block Y */
}

std::forward() пройдет дальше newt именно так, как это было передано push_back(), В результате чего:

  • конструктор копирования T используется, если push_back() передается lvalue, или
  • конструктор движения T используется, если push_back() передано значение.

Посмотреть онлайн демо на http://ideone.com/HjOrap .

Обратите внимание, что это правильно, если push_back() является автономной функцией или функцией-членом не шаблонного класса. Если это функция-член класса шаблона, то сама функция должна принимать тип шаблона в дополнение к типу шаблона класса, поскольку это поведение зависит от T будучи выведенным типом.

Увидеть Универсальные ссылки Скотт Мейерс.

5

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector