c++ - 初始化列表中的 lambda 返回

标签 c++ c++11 lambda initializer-list

让我们看一个现实生活中的例子:

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 成员属性:

...
    const Bimap bimap_;
};

你必须在初始化列表中初始化它,而不是在构造函数体中。它的初始化非常重要,因此您必须委托(delegate)一个函数来计算它的值。您可以使用 lambda 返回的值,利用移动语义(没有临时对象的拷贝):

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;
        }() } {
}

使用这种技术有什么缺点吗?值得这么麻烦吗?我发现它的可读性稍差,但性能如何?

最佳答案

在性能方面,它应该没有那么重要。您不会复制任何 Bitmap 对象,并且您的 lambda 的构造不应该花费任何明显的时间。

但为了可读性,我会在这里创建一个静态成员函数而不是 lambda:

class RuleNameConverter {
public:
    RuleNameConverter(const boost::property_tree::ptree& pt);
private:
    static Bitmap createBitmap(const boost::property_tree::ptree& pt);
};

RuleNameConverter::RuleNameConverter(const boost::property_tree::ptree& pt) :
    bimap_ { createBitmap(pt) } {
}

Bitmap RuleNameConverter::createBitmap(const boost::property_tree::ptree& 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;
}

当您需要使用辅助函数初始化多个成员时,为每个成员创建一个新的 lambda 会导致构造函数初始化列表中出现无法维护的困惑,但是多个辅助函数不需要有这个问题。此外,如果您添加构造函数重载,则可以从多个构造函数轻松调用 createBitmap

或者,如果 createBitmap 的主体不是真正特定于您的 RuleNameConverter,则使用常规的非成员函数。

关于c++ - 初始化列表中的 lambda 返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27401239/

相关文章:

c++ - Visual Studio下CMake构建问题

c++ - 在本地安装 OpenMPI 以与 CUDA 一起使用时出现问题

templates - 是编译器还是我 : Inheriting from variadic template consisting of lambdas

c++ - Python -> C++ 习语 : Storing lambda expressions in a map/container

c# - 使用 ExpressionTree 将委托(delegate) (Action<TObject, TValue>) 检索到索引器的 Setter

c++ - WinDbg 是如何认识源码的?

C++ 嵌套 for 循环不正确的输出

c++ - 正确使用boost lambda

c++ - 如何在 yocto 上移植 grpc helloworld(CPP) 示例

c++ - 什么是匿名对象?