Функция идентификации с идеальной пересылкой

Я хочу написать функцию identity который отлично передает свой аргумент без какой-либо копии. Я бы написал что-то вроде этого

 template< typename V >
inline V&& identity( V&& v )
{
return std::forward< V >( v );
}

Но правильно ли это? Всегда ли он возвращает правильный тип? Это просто вперед v независимо, если это lvalue / lvalue ссылка / временная?

2

Решение

Вы можете использовать пакет параметров в качестве защиты, так что никто не может на самом деле заставить тип, который отличается от того, который был бы выведен в противном случае.
Как минимальный рабочий пример:

#include <type_traits>
#include <utility>

template<typename..., typename V>
constexpr V&& identity(V&& v) {
return std::forward<V>(v);
}

int main() {
static_assert(std::is_same<decltype(identity(42)), int&&>::value, "!");
static_assert(std::is_same<decltype(identity<int>(42)), int&&>::value, "!");
static_assert(std::is_same<decltype(identity<float>(42)), int&&>::value, "!");
// here is the example mentioned by @Jarod42 in the comments to the question
static_assert(std::is_same<decltype(identity<const int &>(42)), int&&>::value, "!");
}

Таким образом, тип возвращаемого значения зависит от фактического типа v параметр, и вы не можете сила копия в любом случае.


Как упоминалось в комментариях @bolov, синтаксис может быстро стать неясным.
В любом случае, как подсказывает @ Jarod42, нужно быть более ясным в том, что мы делаем.

В качестве примера:

template <typename... EmptyPack, typename V, typename = std::enable_if_t<sizeof...(EmptyPack) == 0>>

Как альтернатива:

template <typename... EmptyPack, typename V, std::enable_if_t<sizeof...(EmptyPack) == 0>* = nullptr>

Или даже:

template <typename... EmptyPack, typename V>
constexpr
std::enable_if_t<sizeof...(EmptyPack) == 0, V&&>
identity(V&& v) {
return std::forward<V>(v);
}

Подберите предпочтительный вариант и используйте его, все они должны быть действительными в этом случае.

4

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

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

По вопросам рекламы [email protected]