2012-03-26 5 views
3

так у меня есть мухи строк типа:строка грузиков преобразования строки: лучший вариант производительности

typedef boost::flyweight< std::string, boost::flyweights::intermodule_holder > SymbolName_t; 

и я хочу, чтобы подтолкнуть экземпляр этого в вектор из них, но наивный подход выиграл» т работы:

void PushSome(std::vector <SymbolName_t>& list) 
{ 
    std::string& str = getSomeStr(); 
    list.push_back(str); // <--- won't compile 
} 

так я добавил временный конструктор:

void PushSome(std::vector <SymbolName_t>& list) 
{ 
    std::string& str = getSomeStr(); 
    list.push_back(SymbolName_t(str)); // <--- compiles ok 
} 

мой вопрос: Этот подход оптимален, учитывая ограничения языка? какие преимущества обеспечит реализацию этого каким-либо другим способом, скажем, путем предоставления оператора статического преобразования? Я не считаю неявное преобразование через неявный конструктор допустимым вариантом, потому что это потребует изменения шаблона boost::flyweight

ответ

3

Если у вас есть компилятор C++ 11, вы можете использовать emplace_back вместо push_back, что устраняет необходимость в копии.

+1

И потребность в временном, пока вы на нем. –

1

Из того, что я знаю о C++, ваш вышеприведенный код может быть вашим лучшим вариантом, поскольку вы передаете ссылку на список (не вызвано назначение задания или конструктор копирования), получение ссылки на вашу строку (опять же, отсутствие назначения или конструктора копирования), а затем нажатие только что построенного SymbolName_t в ваш список. К сожалению, STL containers operate on copies of their arguments, поэтому в этом случае будет задействован конструктор копирования или оператор присваивания (я не помню, какой из них использует std::list). Другие варианты могут включать в себя операцию преобразования, но список все равно должен будет создать исходный объект, а затем скопировать его в контейнер STL. Даже с другим контейнером STL это все равно будет правдой. Так что оператор конверсии действительно ничего не купил бы, ИМХО.

Ваш вышеуказанный код (блок компиляции ok) может быть вашим лучшим выбором. В рамках ограничений контейнеров STL я не могу придумать более эффективный метод. Вы могли бы купить некоторую производительность, используя shared_ptr до SymbolName_t, но поскольку boost:flyweight уже должен быть оптимизирован для управления памятью, я не уверен, сколько вы покупаете, если много повторяющихся строк.