【问题标题】:Why boost::any does not hold string literal?为什么 boost::any 不包含字符串文字?
【发布时间】:2013-11-13 09:21:31
【问题描述】:
#include <boost/any.hpp>
#include <list>
#include <string>
#include <vector>

struct _time_t {
    int month;
    int year;
};


int main()
{
    std::string str = "hahastr";
    _time_t t;
    std::vector<boost::any> objVec;
    objVec.push_back(1);
    char* pstr = "haha";
    //boost::any charArr = "haha"; not compile
    //objVec.push_back("haha"); not compile
    objVec.push_back(pstr);
    objVec.push_back(str);
    objVec.push_back(t);
    return 0;
};

注释的代码行无法编译,为什么?我认为字符串文字在大多数情况下可以充当 char*,这是相关的 r-value 和 l-rvalue 吗?

错误信息: test_boost_any.cc

D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocale(336) : wa
rning C4530: C++ exception handler used, but unwind semantics are not enabled. S
pecify /EHsc
e:\projects\framework\boost_1_53_0\boost/any.hpp(122) : error C2536: 'boost::any
::holder<ValueType>::boost::any::holder<ValueType>::held' : cannot specify expli
cit initializer for arrays
        with
        [
            ValueType=const char [5]
        ]
        e:\projects\framework\boost_1_53_0\boost/any.hpp(139) : see declaration
of 'boost::any::holder<ValueType>::held'
        with
        [
            ValueType=const char [5]
        ]
        e:\projects\framework\boost_1_53_0\boost/any.hpp(120) : while compiling
class template member function 'boost::any::holder<ValueType>::holder(ValueType
(&))'
        with
        [
            ValueType=const char [5]
        ]
        e:\projects\framework\boost_1_53_0\boost/any.hpp(47) : see reference to
function template instantiation 'boost::any::holder<ValueType>::holder(ValueType
 (&))' being compiled
        with
        [
            ValueType=const char [5]
        ]
        e:\projects\framework\boost_1_53_0\boost/any.hpp(46) : see reference to
class template instantiation 'boost::any::holder<ValueType>' being compiled
        with
        [
            ValueType=const char [5]
        ]
        test_boost_any.cc(19) : see reference to function template instantiation
 'boost::any::any<const char[5]>(ValueType (&))' being compiled
        with
        [
            ValueType=const char [5]
        ]

【问题讨论】:

  • 编译器告诉你什么?

标签: c++ boost type-erasure boost-any


【解决方案1】:

string-literal 不是指针,它是array of N const char,在你的情况下,因为boost::any 构造函数接收T(推导出为char[5],而不是const char*,数组到指针的转换不能在这里工作),但你不能用initializer-list中的另一个数组初始化一个数组。

【讨论】:

    【解决方案2】:

    Boost.any 值必须有效分配(ValueType 的要求)。然而,字符串文字是一个数组,并且不能在 C++ 中分配数组。

    如果需要,您可以将文字转换为 const char *

    【讨论】:

      【解决方案3】:

      Crufty 数组语义最简单的解决方法是

      boost::any charArr = +"haha"; 
      

      注意使用+ 将char 数组隐式衰减为const char*

      其他人已经解释了数组值语义的问题

      【讨论】:

        【解决方案4】:

        编译器告诉你它不能接受一个数组,例如VS2010会告诉你:

        1>D:\SRC\CDR\Trunk\DRIT\ThirdParty\boost/any.hpp(122): error C2536: 'boost::any::holder<ValueType>::boost::any::holder<ValueType>::held' : cannot specify explicit initializer for arrays
        1>          with
        1>          [
        1>              ValueType=const char [5]
        1>          ]
        1>          D:\SRC\CDR\Trunk\DRIT\ThirdParty\boost/any.hpp(139) : see declaration of 'boost::any::holder<ValueType>::held'
        1>          with
        1>          [
        1>              ValueType=const char [5]
        1>          ]
        1>          D:\SRC\CDR\Trunk\DRIT\ThirdParty\boost/any.hpp(120) : while compiling class template member function 'boost::any::holder<ValueType>::holder(ValueType (&))'
        1>          with
        1>          [
        1>              ValueType=const char [5]
        1>          ]
        1>          D:\SRC\CDR\Trunk\DRIT\ThirdParty\boost/any.hpp(46) : see reference to class template instantiation 'boost::any::holder<ValueType>' being compiled
        1>          with
        1>          [
        1>              ValueType=const char [5]
        1>          ]
        1>          toto.cpp(20) : see reference to function template instantiation 'boost::any::any<const char[5]>(ValueType (&))' being compiled
        1>          with
        1>          [
        1>              ValueType=const char [5]
        1>          ]
        

        “哈哈”的类型,不是const char*,而是const char[5]。 如果您将字符串转换为char*,这将编译:

        boost::any charArr = static_cast<const char*>("haha"); // will compile
        

        例如,您也可以只存储std::string。我怀疑这是因为数组不能存储为指针。你也可以使用boost::arraystd::array(如果你有的话)。

        Here 是一个关于在 Boost 中添加数组支持的讨论的链接。

        【讨论】:

        • 即使是const char * 也可以工作(而且可能会更好)
        【解决方案5】:

        这个问题的简化版本:

        template <typename T>
        class Array
        {
            public:
                Array(T value) : value_(value) {}  
            private:
                T value_;
        };
        
        int main()
        {
            int a[5] = {1,2,3,4,5};
            Array<int[5]> arr = a;
            return 0;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-25
          • 1970-01-01
          相关资源
          最近更新 更多