初始化std::map<std::string, boost::any>
时,值boost::any
确实可以包含任何类型的值,包括std::map
s。但是,它们需要首先明确定义,例如,
#include <map>
#include <boost/any.hpp>
int main() {
std::map<std::string, boost::any> a = {{"y", 2}};
std::map<std::string, boost::any> any = {
{"hh", 4},
{"g", a} // alright
};
}
隐含地尝试同样的事情,例如,
#include <map>
#include <boost/any.hpp>
int main() {
std::map<std::string, boost::any> any = {
{"hh", 4},
{"g", {{"y", 2}}} // mööp
};
}
导致编译错误
error: could not convert ‘{{"hh", 4}, {"g", {{"y", 2}}}}’ from ‘<brace-enclosed initializer list>’ to ‘std::map<std::__cxx11::basic_string<char>, boost::any>’
出了什么问题?有没有办法让初始化适合一个语句?
答案 0 :(得分:9)
好吧,编译器无法知道你的初始化列表最终应该成为什么类型。
给他一些帮助:
#include <map>
#include <boost/any.hpp>
using namespace std;
int main() {
using StringToAny = std::map<std::string, boost::any>;
StringToAny any = {
{"hh", 4},
{"g", StringToAny{{"y", 2}}} // jippie!
};
}
问题解决了。
答案 1 :(得分:6)
一般来说,像这样大括号std::map<K, V>
:
std::map<K, V> m = {{k1, v1}, {k2, v2}, ...};
其中k1
,k2
,等。用于初始化密钥,v1
,v2
,等。 用于初始化映射值。
现在我们可以看到,为了完成您要执行的操作,必须可以从boost::any
的位置初始化映射类型v2
,即{ {1}}。
这是不可能做到的。你做不到
{{"y", 2}}
因此,您尝试初始化地图的方式也无法正常工作。
我看到这个问题是你今天早些时候发布的另一个问题的后续问题,而且你是来自Python背景。您的背景可能会让您相信boost::any a = {{"y", 2}};
本身代表一个地图,{{"y", 2}}
是Python中字典文字的方式。但是,在C ++中并非如此;相反,{'y': 2}
没有类型,甚至根本不是表达式;它是一个特殊的语法类别,名为 braced-init-list 。
braced-init-list 只能用于初始化。它用于确定用于初始化的构造函数,然后将其内容传递给所选的构造函数。尝试从这样的 braced-init-list 初始化{{"y", 2}}
不起作用,因为编译器无法推断出您希望首先将boost::any
转换为映射然后将该映射包装在{{"y", 2}}
。
解决方案是明确执行此转换。
boost::any