boost::any 导致非法访问的类型更改
boost::any type change leading to illegal access
在通过 boost cpp 库一书测试示例时,我注意到更改存储在 boost::any 变量中的类型可能会导致非法访问而不是异常:
好:
boost::any a = 1;
bool *p = boost::any_cast<bool>(&a); // ok, bad cast exception
不好:
boost::any a = std::string { "Boost" };
a = 1;
bool *p = boost::any_cast<bool>(&a); // no exception thrown
std::cout << std::boolalpha << *p << '\n'; // illegal access
因此,我的问题是:这是一个看起来的错误,还是我不知道的与模板使用相关的一些潜在事实?
我对the documentation的理解不同:
Returns: If passed a pointer, it returns a similarly qualified pointer to the value content if successful, otherwise null is returned. If T is ValueType, it returns a copy of the held value, otherwise, if T is a reference to (possibly const qualified) ValueType, it returns a reference to the held value.
Throws: Overloads taking an any pointer do not throw; overloads taking an any value or reference throws bad_any_cast if unsuccessful.
所以:
转换成败取决于存储类型和目标类型。
不过,失败的表现取决于您是否将指针传递给 any_cast
。如果传递一个指针,表现就是一个nullptr
;否则,表现是一个例外。
例如考虑这段代码:
#include <boost/any.hpp>
#include <iostream>
int main() {
boost::any a = 1;
这似乎与你问题中的陈述相矛盾 - 因为它需要一个指针,所以它不会抛出,但指针是 nullptr
:
bool *p = boost::any_cast<bool>(&a);
// Prints true
std::cout << std::boolalpha << (p == nullptr) << std::endl;
这是正常情况下的样子:
int *q = boost::any_cast<int>(&a);
// Prints false
std::cout << std::boolalpha << (q == nullptr) << std::endl;
这会抛出异常,因为它不需要指针:
try {
boost::any_cast<bool>(a);
}
catch(...) {
std::cout << "caught" << std::endl;
}
字符串存储类型相同:
a = std::string { "Boost" };
p = boost::any_cast<bool>(&a);
// Prints true
std::cout << std::boolalpha << (p == nullptr) << std::endl;
try {
boost::any_cast<bool>(a);
}
catch(...) {
std::cout << "caught again" << std::endl;
}
}
在通过 boost cpp 库一书测试示例时,我注意到更改存储在 boost::any 变量中的类型可能会导致非法访问而不是异常:
好:
boost::any a = 1;
bool *p = boost::any_cast<bool>(&a); // ok, bad cast exception
不好:
boost::any a = std::string { "Boost" };
a = 1;
bool *p = boost::any_cast<bool>(&a); // no exception thrown
std::cout << std::boolalpha << *p << '\n'; // illegal access
因此,我的问题是:这是一个看起来的错误,还是我不知道的与模板使用相关的一些潜在事实?
我对the documentation的理解不同:
Returns: If passed a pointer, it returns a similarly qualified pointer to the value content if successful, otherwise null is returned. If T is ValueType, it returns a copy of the held value, otherwise, if T is a reference to (possibly const qualified) ValueType, it returns a reference to the held value.
Throws: Overloads taking an any pointer do not throw; overloads taking an any value or reference throws bad_any_cast if unsuccessful.
所以:
转换成败取决于存储类型和目标类型。
不过,失败的表现取决于您是否将指针传递给
any_cast
。如果传递一个指针,表现就是一个nullptr
;否则,表现是一个例外。
例如考虑这段代码:
#include <boost/any.hpp>
#include <iostream>
int main() {
boost::any a = 1;
这似乎与你问题中的陈述相矛盾 - 因为它需要一个指针,所以它不会抛出,但指针是 nullptr
:
bool *p = boost::any_cast<bool>(&a);
// Prints true
std::cout << std::boolalpha << (p == nullptr) << std::endl;
这是正常情况下的样子:
int *q = boost::any_cast<int>(&a);
// Prints false
std::cout << std::boolalpha << (q == nullptr) << std::endl;
这会抛出异常,因为它不需要指针:
try {
boost::any_cast<bool>(a);
}
catch(...) {
std::cout << "caught" << std::endl;
}
字符串存储类型相同:
a = std::string { "Boost" };
p = boost::any_cast<bool>(&a);
// Prints true
std::cout << std::boolalpha << (p == nullptr) << std::endl;
try {
boost::any_cast<bool>(a);
}
catch(...) {
std::cout << "caught again" << std::endl;
}
}