Boost.Optional で Ruby の || 演算子のような挙動を行う

さて、Ruby の || 演算子は次のような挙動になります。

n1 = 42 || 12
puts n1 # => 42

n2 = false || 12
puts n2 # => 12

n3 = 42 || false
puts n3 # => 42


このように Ruby の || 演算子は最初に真になった値を返します。
これを Boost.Optional を使って C++ でも行なってみました。

[ソース]

#include <iostream>
#include <boost/optional/optional.hpp>
#include <boost/optional/optional_io.hpp>


template<typename T>
boost::optional<T>
operator ||(boost::optional<T> a, boost::optional<T> b){
    return a ? a : b ? b : boost::none;
}

template<typename T>
auto
operator ||(boost::optional<T> a, T b)
->decltype(a || boost::make_optional(b)){
    return a || boost::make_optional(b);
}

template<typename T>
auto
operator ||(T a, boost::optional<T> b)
->decltype(boost::make_optional(a) || b){
    return boost::make_optional(a) || b;
}

template<typename T>
boost::optional<T>
operator ||(boost::optional<T> a, boost::none_t){
    return a;
}

template<typename T>
boost::optional<T>
operator ||(boost::none_t, boost::optional<T> b){
    return b;
}



template<typename T>
boost::optional<T>
division(T a, T b){
    return b == 0 ? boost::none : boost::make_optional(a / b);
}


int
main(){
    auto n1 = boost::make_optional(42) || boost::make_optional(12);
    std::cout << n1 << std::endl;

    auto n2 = boost::none || boost::make_optional(12);
    std::cout << n2 << std::endl;

    auto n3 = boost::make_optional(42) || boost::none;
    std::cout << n3 << std::endl;


    std::cout << (division(9, 3) || 1) << std::endl;
    std::cout << (division(4, 0) || 1) << std::endl;
    std::cout << (division(4, 0) || division(35, 7)) << std::endl;

    return 0;
}

[出力]

 42
 12
 42
 3
 1
 5


これは地味に便利な書き方じゃなかろうか。
右辺にデフォルト値とかかけるし。
ただし、Ruby の場合とは違い右辺の式が評価されてしまうのでぐぬぬ…というところ。