Boost ::与指针与值的混淆

boost::any confusion with pointers vs values

本文关键字:指针 Boost      更新时间:2023-10-16

我花了一段时间才弄清楚这一点,但是boost::any的语义令人困惑。

具有价值类型,您可以这样使用:

int value = 100;
boost::any something;
something = value;
//...later...
int value = boost::any_cast<int>(&something);

此代码很清楚并且很有意义,但是内部存储value作为副本。这意味着对于我放置在boost::any中的较大物体,它们将被复制。同样,我用此替换void*的任何函数都将期望当我修改boost::any对象中包含的值时(由于它复制它,因此不会发生)。

所以,如果我把指针放入其中,事情就会变得很奇怪:

int value = 100;
boost::any something;
something = &value;
//...later...
int* value = *boost::any_cast<int*>(&something);

在这种情况下,我必须放弃返回值,因为boost::any_cast返回int**!我也没有检查过,但是我认为如果something.empty() == true,这可能会崩溃。这根本不是直接的。

我不想将值存储在我的boost::any中,我希望它仅在指针上起作用,而在语义上更接近void*。指针,指针散开,混合了某种类型的安全。从本质上讲,我想要的是boost::any_pointer或类似的东西。有没有办法禁止boost::any接受除指针以外的任何东西?如果没有,是否有boost::any的替代方法可以给我我要寻找的语义?

您正在使用Any_cast错误:

基本上有两个(三)个口味。

  • 参考任何内容并返回值或参考内容
  • 将指针指向任何人并将指针返回到内容

示例:

#include <boost/any.hpp>
int main()
{
    // Any holding a value
    {
        boost::any any_value(1);
        // Throws bad_any_cast if the content is not 'int' (in this case):
        int  value = boost::any_cast<int>(any_value);
        // Throws bad_any_cast if the content is not 'int' (in this case):
        int& reference = boost::any_cast<int&>(any_value);
        // Returns a null pointer if the content is not 'int' (in this case):
        int* pointer = boost::any_cast<int>(&any_value);
    }
    // Any holding a pointer (which is nothing else but a value)
    {
        int integer = 0;
        boost::any any_ptr(&integer);
        // Throws bad_any_cast if the content is not 'int*' (in this case):
        int * pointer = boost::any_cast<int*>(any_ptr);
        // Throws bad_any_cast if the content is not 'int*' (in this case):
        int*& pointer_reference = boost::any_cast<int*&>(any_ptr);
        // Returns a null pointer if the content is not 'int*' (in this case):
        int** pointer_pointer = boost::any_cast<int*>(&any_ptr);
    }
}

另请参阅:http://en.cppreference.com/w/cpp/experement/any and and and http://en.cppreference.com/w/cpp/experement/experement/any_cast<>

note :我假设您要在boost::any中存储Pointer,因为您在boost::any_pointer的行中寻找某些东西(尽管不存在)。<<<<<<<<<<<<<<<<<<<<

boost::any_cast返回指向其中存储的实际值(固定器内部的 held对象)。因此,除非您实际要稍后再复制,否则它可以保存副本。

template<typename ValueType>
    ValueType * any_cast(any * operand) BOOST_NOEXCEPT
    {
        return operand && operand->type() == boost::typeindex::type_id<ValueType>()
            ? &static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
            : 0;
    }

您总是可以围绕boost::any创建包装器,以仅允许指针类型:

class MyAny {
public:
  template <typename T, 
        typename = typename std::enable_if<std::is_pointer<std::remove_cv<T>::type>::value>::type>
  MyAny(T ptr): any_(ptr) {}
 template <typename ValueType>
 ValueType operator*() {
     return *boost::any_cast<ValueType>(&any_);
 }
private:
  boost::any any_
};

上面是一个粗糙的代码,我没有编译和测试。

std::enable_if类型特征在C 11中可用,但也可以在Boost中找到。这就是将您的MyAny限制为仅指针类型的原因。

尽管这是一个古老的问题,但我想在问问题的序言中指出一个简单的误解[我认为]:

int value = 100;
boost::any something;
something = &value;                                    // 1)
//...later...
int* value = *boost::any_cast<int*>(&something);       // 2)

1)在某物中保存了" int *"。

2)这基本包含几个步骤:

  • "&amp; shosing"获得某物的地址,即返回" boost :: any *"
  • " boost :: any_cast()"现在将此地址投放给指向int的指针 - 这可能不是void.pointer想要的。而且我不知道 - 以及是否,为什么 - 这似乎有效。
  • 然后您退出"*boost :: ...",即取消"&amp;"从第一步再次开始。

我的想法,void.pointer想在这里做,更多的是以下几行:

int* value = boost::any_cast<int*>(something);

ps:我希望将其放入简单的评论中,而不是一个完整的答案 - stackoverflow,但是我要求我先收集足够的积分,所以...