2015-02-05 1 views
3

Мне было интересно, есть ли элегантный способ отличить boost::optional<A> до boost::optional<B>, когда B может быть построен из A, хотя и явно. Это работает:boost :: optional и преобразование типа

# include <boost/optional.hpp> 

class Foo 
{ 
    int i_; 
public: 
    explicit Foo(int i) : i_(i) {} 
}; 

int main() 
{ 
    boost::optional<int> i; 
    ... // i gets initialized or not 
    boost::optional<Foo> foo; 
    foo = boost::optional<Foo>(bool(i), Foo(i.value_or(0 /*unused value*/))); 
    return 0; 
} 

, но необходимость вставить там какое-то значение, которое никогда не будет использоваться, кажется неудобным. Любое лучшее предложение?

ответ

6
template<class T, class U> 
boost::optional<T> optional_cast(U&& u) { 
    if (u) return T(*std::forward<U>(u)); 
    else return {}; 
} 

будет забавно также работать с указателями.

int main() { 
    boost::optional<int> i; 
    ... // i gets initialized or not 
    boost::optional<Foo> foo = optional_cast<Foo>(i); 
    return 0; 
} 

В C++ 03

template<class T, class U> 
boost::optional<T> optional_cast(U const& u) { 
    if (u) return T(*u); 
    else return boost::none; 
} 

будет работать вместо этого, но менее эффективным в ряде случаев.