I'm using the function tryValue
very often in my projects. It is simple wrapper around boost::any
, that simplifies greatly its everyday usage.
#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;
}
Now, I extended this function, so that I can deal with reference. This has the opportunity to change the value inside my boost-optional
in place.
Now it is tiresome to keep in mind, if I have to write tryValue
or tryValueRef
. The function tryValue
should figure out on its own, whether T
is a reference (or even pointer) or not. The template function std::is_reference<T>
should do this job, but I have no idea how to effectively use it.
A second part, that I don't understood yet, is why the return value of tryValueRef
needs an extra *
to set the value.
Solution
A simple renaming of the function was sufficient to make it work.
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;
}