【问题标题】:How to work out types required for std::for_each lambda function如何计算 std::for_each lambda 函数所需的类型
【发布时间】:2017-01-15 13:10:32
【问题描述】:

我对如何确定在 std::for_each 中使用 lambda 函数所需的类型感到困惑。在这种情况下,我似乎不能使用 auto 作为参数(Visual Studio 2013 无论如何都会抱怨)。

在下面的代码中,我原以为我会使用 section 作为 for_each 函数的类型,但实际上我必须使用

const std::pair<std::string, std::unordered_map<std::string, std::string> >

对于这种情况下的“内部”类型,我应该使用什么?

我的主要问题是如何确定使用哪种类型?

#include <iostream>
#include <string>
#include <unordered_map>
#include <algorithm>


// key=value pairs within a section
typedef std::unordered_map<std::string, std::string> keyvalue;

// [section1] - top level
typedef std::unordered_map< std::string, std::unordered_map<std::string, std::string> > sections;

class config
{
public:
    config() {
        setup();
    }
    typedef sections::iterator iterator;
    iterator begin() { return sections_.begin(); }
    iterator end() { return sections_.end(); }


private:
    sections sections_;

    void setup() { 
        // obviously we wouldn't hard code like this in a real program
        sections_["programming languages"].insert(std::make_pair("C", "imperative"));
        sections_["programming languages"].insert(std::make_pair("C++", "OOP"));
        sections_["programming languages"].insert(std::make_pair("Java", "OOP"));
        sections_["programming languages"].insert(std::make_pair("Haskell", "functional"));
        sections_["programming languages"].insert(std::make_pair("Prolog", "logic"));
    }
};


int main() {
    config cfg;
    std::for_each(cfg.begin(), cfg.end(), [](const std::pair<std::string, std::unordered_map<std::string, std::string> > sec) {
        std::cout << "section name: " << sec.first << std::endl;

        // what is inner type - thought it would be keyvalue ???
        //std::for_each(sec.second.begin(), sec.second.end(), [](const keyvalue& pr) {   
            //std::cout << "first: " << pr << std::endl;
        //});
    });

    // I thought type would be sections ???
    //std::for_each(cfg.begin(), cfg.end(), [](const sections& sec) {
    //  std::cout << "section name: " << sec.first << std::endl;
    //});
}

【问题讨论】:

  • 你为什么不用for (auto &amp;&amp;sec : cfg)

标签: c++11 lambda


【解决方案1】:

你也可以像这样使用decltype

    config cfg;
    std::for_each(cfg.begin(), cfg.end(), [](const decltype(*cfg.begin())& sec) {
        std::cout << "section name: " << sec.first << std::endl;

        std::for_each(sec.second.begin(), sec.second.end(), [](const decltype(*sec.second.begin())& pr) {   
        std::cout << "first: " << pr.first << std::endl;
        });
    });

我不能 100% 确定引用类型对此有何影响,因此删除它可能更合适,例如 const std::remove_reference&lt;decltype(*cfg.begin())&gt;::type&amp; sec

虽然需要注意的是VS2013 ItelliSense在decltype方面存在问题,即使编译正常也会标记为错误。

STL 容器总是定义一个value_type,所以在这种情况下,您可以使用decltype(inst)::value_type,并且不需要remove_reference 恶作剧。所以我建议你也像这样在你的类型中添加一个value_type typedef:

class config
{
public:
    typedef sections::value_type value_type;

那么你可以这样做:

    config cfg;
    std::for_each(cfg.begin(), cfg.end(), [](const decltype(cfg)::value_type& sec) {
        std::cout << "section name: " << sec.first << std::endl;

        std::for_each(sec.second.begin(), sec.second.end(), [](const decltype(sec.second)::value_type& pr) {   
        std::cout << "first: " << pr.first << std::endl;
        });
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 2010-09-18
    相关资源
    最近更新 更多