Why boost::any does not hold string literal?

我是研究僧i 提交于 2019-12-01 20:22:59

问题


#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;
};

the commented code lines do not compile, why? I think string literal could act as char* in most circumstance, is this related r-value and l-rvalue?

error message: 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]
        ]

回答1:


string-literal is not a pointer, it's array of N const char, in your case, since boost::any constructor receive T (which is deduced to char[5], not to const char*, array-to-pointer conversion cannot work here), but you cannot initialize an array by another array in an initializer-list.




回答2:


Boost.any values must be valid to assign (requirement of ValueType). A string literal is however an array and arrays cannot be assigned in C++.

You can just cast the literal to a const char * if you need that.




回答3:


The simplest workaround for crufty array semantics in C here is

boost::any charArr = +"haha"; 

Note the use of + to implicitly decay the char array to a const char*

Others have explained the problem with array value semantics




回答4:


The compiler tells you that it cannot accept an array, for example VS2010 will tell you :

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>          ]

The type of "haha", is not a const char* but a const char[5]. If you cast the string into a char* this will compile:

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

Alternatively, you could just store a std::string for example. I suspect this is because an array cannot be stored as a pointer. You could also use boost::array or std::array (if you have it).

Here is a link to a discussion to add array support in Boost.




回答5:


A simpified version of this problem:

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;
}


来源:https://stackoverflow.com/questions/19949887/why-boostany-does-not-hold-string-literal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!