我花了一些时间才弄明白这一点,但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
的替代品可以为我提供我正在寻找的语义?
答案 0 :(得分:1)
注意:我假设您要在boost::any
中存储指针,因为您正在查找boost::any_pointer
行(虽然不存在)。< / p>
boost::any_cast
返回指向存储在其中的实际值的指针(holder中的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
限制为仅指针类型的原因。
答案 1 :(得分:1)
您正在使用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/experimental/any和http://en.cppreference.com/w/cpp/experimental/any/any_cast
答案 2 :(得分:0)
尽管这是一个很老的问题,但我还是想在提出的问题的序言中指出一个简单的误解[我认为]:
int value = 100;
boost::any something;
something = &value; // 1)
//...later...
int* value = *boost::any_cast<int*>(&something); // 2)
1)这样可以将“ int *”保存在某些内容中。
2)这实际上包含几个步骤:
void.pointer我想在这里做的事情,大致如下:
int* value = boost::any_cast<int*>(something);
。
PS:我希望将其放在一个简单的注释中,而不是一个完整的答案-但是stackoverflow要求我首先收集足够的分数,所以...