Я пытаюсь добиться следующей оптимизации в моей библиотеке контейнеров:
- при вставке элемента со ссылкой на lvalue скопируйте его во внутреннее хранилище;
- но при вставке элемента с rvalue-ссылкой переместить , если поддерживается.
Предполагается, что оптимизация будет полезной, например, если тип содержащегося элемента - что-то вроде std::vector
, где перемещение, если возможно, даст существенное ускорение.
Однако до сих пор я не смог разработать какую-либо рабочую схему для этого. Мой контейнер довольно сложный, поэтому я не могу просто скопировать код insert()
несколько раз: он большой. Я хочу сохранить весь «настоящий» код в каком-то внутреннем помощнике, скажем, do_insert()
(может быть шаблонным), и различные insert()
-подобные функции просто вызовут это с разными аргументами.
Код моей лучшей ставки для этого (прототип, конечно, без каких-либо реальных действий):
#include <iostream>
#include <utility>
struct element
{
element () { };
element (element&&) { std::cerr << "moving\n"; }
};
struct container
{
void insert (const element& value)
{ do_insert (value); }
void insert (element&& value)
{ do_insert (std::move (value)); }
private:
template <typename Arg>
void do_insert (Arg arg)
{ element x (arg); }
};
int
main ()
{
{
// Shouldn't move.
container c;
element x;
c.insert (x);
}
{
// Should move.
container c;
c.insert (element ());
}
}
Однако, это не работает по крайней мере с GCC 4.4 и 4.5: он никогда не печатает "перемещение" на stderr. Или то, чего я хочу, невозможно достичь, и поэтому emplace()
-подобные функции существуют в первую очередь?