如何将:: any_cast提升为std :: string

时间:2015-07-07 16:00:27

标签: c++ c++11 boost

我有这个测试片段

#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;一个出路吗?

3 个答案:

答案 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看起来很奇怪,但它可以正常工作,因为该函数已重载。