преобразование строки в маховики: лучший вариант производительности - PullRequest
3 голосов
/ 26 марта 2012

, поэтому у меня есть налетный вес типа строки:

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 шаблон

Ответы [ 2 ]

3 голосов
/ 26 марта 2012

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

1 голос
/ 26 марта 2012

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

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

...