我有这个测试片段
#include <boost/any.hpp>
#include <iostream>
#include <vector>
#include <bitset>
#include <string>
class wrapper {
int value;
char character;
std::string str;
public:
wrapper(int i, char c, std::string s) {
value = i;
character = c;
str = s;
}
void get_data(){
std::cout << "Value = " << value << std::endl;
std::cout << "Character = " << character << std::endl;
std::cout << "String= " << str << std::endl;
}
};
int main(){
std::vector<boost::any> container;
container.push_back(10);
container.push_back(1.4);
container.push_back("Mayukh");
container.push_back('A');
container.push_back(std::bitset<16>(255) );
wrapper wrap(20, 'M', "Alisha");
container.push_back(wrap);
std::cout << boost::any_cast<int>(container[0]) << std::endl;
std::cout << boost::any_cast<double>(container[1]) << std::endl;
std::cout << boost::any_cast<std::string>(container[2]);
std::cout << boost::any_cast<char>(container[3]) << std::endl;
std::cout << boost::any_cast<std::bitset<16>>(container[4]);
auto p = boost::any_cast<wrapper>(container[5]);
p.get_data();
return 0;
}
在此boost::any_cast
中为std::string
提供了bad_casting异常。这意味着由于某种原因,它无法将boost::any
强制转换为std::string
。而其他类如bitset
或我自己的用户定义类正在运行。你能告诉我为什么&amp;一个出路吗?
答案 0 :(得分:12)
"Mayukh"
不是std::string
,而是一个包含7个字符const
的{{1}}数组。在C ++ 14中,{'M', 'a', 'y', 'u', 'k', 'h', '\0'}
是"Mayukh"s
之后的std::string
。
在C ++ 11中,using namespace std::literals::string_literals;
也是std::string("Mayukh")
。
std::string
仅支持转换回完全相同的类型(好吧,直到某些衰减/ const /等)。它不支持类型之间的转换。见boost any documentation:
包含不同类型值但不尝试在它们之间进行转换的歧视类型,即
boost::any
严格保留为int,并且不能隐式转换为5
或"5"
。他们对解释的漠不关心,但对类型的意识有效地使他们成为单一价值观的安全,通用容器,没有范围可以避免模糊转换带来的惊喜。
可以通过额外的智能转换来扩充5.0
。例如,一个伪任务,它接受传入类型,并可能自动转换它(因此它不会存储any
:它将所有带符号的整数类型转换为short
并且无符号转换为{{ 1}},它会在存储之前将int64_t
转换为uint64_t
等。
答案 1 :(得分:6)
那是因为"Mayukh"
不是std::string
。它是一个const char[7]
,会衰变为const char*
:
boost::any a = "Mayukh";
std::cout << a.type().name() << '\n'; // prints PKc, pointer to const char
if (boost::any_cast<const char*>(&a)) {
std::cout << "yay\n"; // prints yay
}
如果您希望能够使用any_cast<std::string>
,则需要将其作为std::string
投放:
container.push_back(std::string("Mayukh"));
答案 2 :(得分:0)
这不是对问题正文的解答,而是对标题的帮助,以帮助也从Google来的其他人:
bool is_char_ptr(const boost::any & operand)
{
try {
boost::any_cast<char *>(operand);
return true;
}
catch (const boost::bad_any_cast &) {
return false;
}
}
std::string any2string(boost::any anything)
{
if (anything.type() == typeid(int)) {
return std::to_string( boost::any_cast<int>(anything) );
}
if (anything.type() == typeid(double)) {
return std::to_string(boost::any_cast<double>(anything));
}
if (is_char_ptr(anything)) {
return std::string(boost::any_cast<char *>(anything));
}
if (boost::any_cast<std::string>(anything)) {
return boost::any_cast<std::string>(anything);
}
}
最后一个if看起来很奇怪,但它可以正常工作,因为该函数已重载。