C++ 可以简化这个表达式吗?
假设我有一个带有成员变量的类:C++ 可以简化这个表达式吗?,c++,stl,c++11,C++,Stl,C++11,假设我有一个带有成员变量的类: std::unordered_map<KeyType, std::shared_ptr<ValueType>> myMap 出于这个原因,我建议使用复杂的模板,比如assoc容器,这样您就可以执行以下操作: typedef std::unordered_map<KeyType, std::shared_ptr<ValueType>> map_type; map_type myMap; //do with map
std::unordered_map<KeyType, std::shared_ptr<ValueType>> myMap
出于这个原因,我建议使用复杂的模板,比如assoc容器,这样您就可以执行以下操作:
typedef std::unordered_map<KeyType, std::shared_ptr<ValueType>> map_type;
map_type myMap;
//do with map
std::for_each(myMap.begin(), myMap.end(),
[](typename map_type::value_type& pair){
pair.second->someMethod();
});
decltype获取对象的类型,您需要使用模板类中定义的typename,为此,您需要使用
typename
关键字。这是必要的,以防模板专业化没有那样的typedef。我根本不需要lambda。与其他标准算法不同,for_each()
的表达力和可读性并不比等价的for
更高
for (auto& p : myMap)
p.second->someMethod();
for (auto p = myMap.begin(); p != myMap.end(); ++p)
p->second->someMethod();
我制作了一个宏,如下所示: //来自容器名称的匿名lambda类型推断
#define _A(container)\
std::remove_reference<decltype(*std::begin(container))>::type
注:
如果键入
[](const\u A(myMap)和pair)
,则需要删除引用以保持常量,否则和将删除常量声明。使用命名空间std代码>会把它缩短一点。@Soohjun天哪,不要这样做:(@111111:它在定义中的局部作用域很小,只是不在全局或标题中。@JonPurdy我知道它可以在某些情况下使用,但不使用它要容易得多。我更愿意看到使用std::unordered_map
或其他任何东西,而不是包含整个名称空间。我真的不认为推荐at作为中的注释这个问题很有建设性。@111111:我不同意。说“在合适的时候做”比“不做”更有建设性。它是否更有帮助是另一个问题。事实上,我甚至会说,for_each
在新的语法范围内同样不受欢迎。你以前有过一些好处(以编写谓词为代价),但现在?这根本不值得。@Klaim:这一点很好。再说一遍,对于
,总是有一个普通的。如果不是因为打字问题,对于_each()
可能会节省一些击键次数,但事实上,for
在许多情况下仍然是最重要的。有趣的是,这一切都是在我今天读了这篇文章之后发生的:但在这种情况下,使用一个简单的range for循环可能是最好的答案?@JonPurdy实际上,我是在评论MatthieuM。注意到我发现了错误,因为有有趣的差异grivescorbett:这篇文章是我写的。for
有时更好。PNo不是,你可以在每种算法中使用它,而不仅仅是在每个算法中使用它。我不是指宏本身(虽然,我通常使用typedef
,因此它在我的编码风格中没有那么有用),我是指你写的每个的。for(auto&p:myMap){p.second->someMethod();}
要短得多。是的,在foreach的情况下,但我认为它有点像关于所有算法的一般问题(如果您对所有内容使用不同的算法而不是for\forloops,那么代码的可读性就会大大提高)。现在,使用auto,您不需要键入所有内容。我仍然喜欢typedef
,因为std::map
没有语义,但是IdNameMap
有语义。这不仅仅是为了缩短内容:)此外,函数参数仍然需要键入,我越来越倾向于使用短函数。老实说,我也在各处键入def。但是,这些信息(IdNameMap)也可以是变量名。而且,我的答案没有被认为是正确的,这让我很恼火,因为我认为这是这个问题的最佳答案:)
std::for_each(myMap.begin(), myMap.end(),
[](typename decltype(myMap)::value_type& pair){
pair.second->someMethod();
});
for (auto& p : myMap)
p.second->someMethod();
for (auto p = myMap.begin(); p != myMap.end(); ++p)
p->second->someMethod();
#define _A(container)\
std::remove_reference<decltype(*std::begin(container))>::type
std::for_each(myMap.begin(), myMap.end(), [](_A(myMap)& pair) {
pair.second->someMethod();
});