Я хочу разработать небольшой полиморфный класс со стиранием типа, и мне интересно, какая версия шаблонизированного конструктора лучше и должна использоваться.
Мы можем передать по значению:
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
это не сам класс и класс не копируется). Есть идеи? Обе версии выглядят одинаково для меня.
Они не эквивалентны, и иногда одно желательно по сравнению с другим. звездный разговор Николая Йосуттиса час стоит поговорить только об этом. Я настоятельно рекомендую посмотреть его хотя бы один раз.
Лично, если вы не столкнетесь с особым случаем, когда преобразования стоят дорого, и вы хотите максимально избежать временных затрат, я бы предложил просто передать по значению и 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&&)
.
Еще раз — приведенный выше пример был основан на разговоре, который я связал в начале ответа. Это действительно стоит смотреть.
Других решений пока нет …