Передача по значению или универсальная ссылка

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

Мы можем передать по значению:

class A
{
...
template< typename T >
A( T t ) { /* create the underlying model via std::move */ }
...
};

или мы можем использовать универсальную ссылку:

class A
{
...
template< typename T >
A( T &&t ) { /* create the underlying model via std::forward */ }
...
};

(Универсальная ссылка должна быть включена, если для случая, когда T это не сам класс и класс не копируется). Есть идеи? Обе версии выглядят одинаково для меня.

8

Решение

Они не эквивалентны, и иногда одно желательно по сравнению с другим. звездный разговор Николая Йосуттиса час стоит поговорить только об этом. Я настоятельно рекомендую посмотреть его хотя бы один раз.

Лично, если вы не столкнетесь с особым случаем, когда преобразования стоят дорого, и вы хотите максимально избежать временных затрат, я бы предложил просто передать по значению и std::moveспор.

Случай где T&& более эффективно:

struct foo {
std::string bar;

template <typename T>
foo(T&& t)
:bar(std::forward<T>(t)){}
};

против:

struct foo {
std::string bar;

foo(std::string t)
:bar(std::move(t)){}
};

когда вы делаете:

int main() {
foo f("some char*");
}

В первом случае (совершенная пересылка) вы просто создаете std::string с const char* аргумент. Во втором случае вы создаете один временный (t от "some char*") и один пустой std::string объект, затем вы применяете одну операцию перемещения. Это не конец света, но первая версия просто более эффективна.

Чтобы быть абсолютно ясно о производительности:

  • Первая версия использует 1 распределение

  • вторая версия использует 1 распределение и 1 ход

и по переехать Я не имею ввиду std::move, поскольку он не генерирует код (это просто приведение). От переехать Я имею в виду код, который должен быть выполнен, который фактически перемещается из строки, которая является частью std::string(std::string&&).

Еще раз — приведенный выше пример был основан на разговоре, который я связал в начале ответа. Это действительно стоит смотреть.

5

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

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

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