我很困惑如何计算在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;
//});
}
答案 0 :(得分:0)
您也可以像这样使用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<decltype(*cfg.begin())>::type& sec
虽然应该注意到VS2013 ItelliSense在decltype方面遇到了麻烦,即使它编译得很好也会将其标记为错误。
STL容器始终定义value_type
,因此在这种情况下,您可以使用decltype(inst)::value_type
并且您不需要remove_reference shenanigans。所以我建议你也为你的类型添加一个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;
});
});