我tryValue
在我的项目中经常使用该功能。它是一个简单的包装器boost::any
,大大简化了它的日常使用。
#include <boost/optional.hpp>
#include <boost/any.hpp>
#include <boost/optional/optional_io.hpp>
#include <iostream>
template<typename T>
boost::optional<T> tryValue(const boost::any& any) {
try {
boost::optional<T> ret(boost::any_cast<T>(any));
return ret;
}
catch (...) {
}
return boost::none;
}
template<typename T>
boost::optional<T> tryValueRef(boost::any& any) {
try {
boost::optional<T> ret(boost::any_cast<T>(any));
return ret;
}
catch (...) {
}
return boost::none;
}
int main(int, char**) {
boost::any x(5);
auto u = tryValue<int>(x);
u = 6;
std::cout << boost::any_cast<int>(x) << std::endl;
auto r = tryValueRef<int&>(x);
*r = 8; // Here I need a *? Why is that?
std::cout << boost::any_cast<int>(x) << std::endl;
}
现在,我扩展了这个函数,以便我可以处理引用。这有机会改变我里面的价值boost-optional
。
现在记住,如果我必须写tryValue
或tryValueRef
. 该函数tryValue
应该自己弄清楚是否T
是引用(甚至是指针)。模板功能std::is_reference<T>
应该可以完成这项工作,但我不知道如何有效地使用它。
第二部分,我还不明白,为什么返回值tryValueRef
需要一个额外*
的值来设置值。
解决方案
对该函数进行简单的重命名就足以使其工作。
template<typename T>
boost::optional<T> tryValue(const boost::any& any) {
try {
boost::optional<T> ret(boost::any_cast<T>(any));
return ret;
}
catch (...) {
}
return boost::none;
}
template<typename T>
boost::optional<T> tryValue(boost::any& any) {
try {
boost::optional<T> ret(boost::any_cast<T>(any));
return ret;
}
catch (...) {
}
return boost::none;
}
int main(int, char**) {
boost::any x(5);
auto u = tryValue<int>(x);
u = 6;
std::cout << boost::any_cast<int>(x) << std::endl;
auto v = tryValue<int&>(x);
*v = 7;
std::cout << boost::any_cast<int>(x) << std::endl;
}