Я очень часто использую функцию 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;
}