Давайте посмотрим реальный пример из жизни:лямбда возвращение в списке инициализатора
class RuleNameConverter {
public:
RuleNameConverter(const boost::property_tree::ptree& pt);
int toIdentifier(const std::string& name) const;
std::string toName(const int id) const;
private:
using Bimap = boost::bimap<std::string, int>;
Bimap bimap_;
};
Если конструктор это:
RuleNameConverter::RuleNameConverter(const boost::property_tree::ptree& pt) {
for (const auto& item : pt) {
if (item.first == "rule") {
auto name = item.second.get <std::string> ("<xmlattr>.name");
auto id = item.second.get<int>("<xmlattr>.id");
bimap_.insert(Bimap::value_type { name, id });
}
}
}
Предположим, вы хотите константный атрибут в члена:
...
const Bimap bimap_;
};
Вы должны инициализировать его в списке инициализаторов, а не в конструкторе b оды. Инициализация не является тривиальной, поэтому вы должны делегировать функцию для вычисления ее значения. Вы можете использовать значение, возвращаемое лямбда, принимая преимущества этого шага семантики (без копирования временных объектов):
RuleNameConverter::RuleNameConverter(const boost::property_tree::ptree& pt) :
bimap_ { [&pt]() {
Bimap results;
for (const auto& item : pt) {
if (item.first == "rule") {
auto name = item.second.get <std::string> ("<xmlattr>.name");
auto id = item.second.get<int>("<xmlattr>.id");
results.insert(Bimap::value_type {name, id});
}
}
return results;
}() } {
}
Существуют ли какие-либо недостатки в использовании этого метода? Это стоит того? Я нахожу его немного менее удобочитаемым, но как насчет производительности?
Хм. Я бы дважды проверял правила области захвата только для того, чтобы убедиться, что там нет причуды (вы находитесь в странном контексте) - возможно, нет, после 2 стандартных версий, особенно на практике. – Yakk
Изменить 'return results;' to 'return std :: move (results);'. Да, у компиляторов есть RVO, но этот способ переводится многословным. – GreenScape
@GreenScape Я помню, что стандарт C++ 11 требует RVO в этом случае, правильно? –