C++
C#

C++でC#の??演算子風なものを作ってみた

追記

11/26日 左辺がfalseだとしても右辺が評価されてしまう問題があったので遅延評価されるように変更

C#の??演算子(null 合体演算子)

??演算子は、左側がnullでない場合は左側を返し、nullである場合には右側を返す2項演算子です

    class Program
    {
        static void Main(string[] args)
        {
            int? a=null;
            a=a??5;

            Console.WriteLine(a); //5
        }
    }

C++でも似たようなものを作ってみる

nullptrかのチェックにしても良かったが、std::optionalとかとも統一するためにboolでのチェックとし、falseだった場合にした

FalseIf.hpp
#include<functional>


constexpr struct FalseIf
{
    template<class T>
    struct Generator
    {
        std::function<T()> generator;
    };
    template<class T>
    auto operator()(T&& generator)const->Generator<decltype(generator())>
    {
        return Generator<decltype(generator())>{generator};
    };
    template<class T, class U>
    friend auto operator |(T&& l, const Generator<U>& r)
        ->decltype(l ? std::forward<T>(l) : r.generator())
    {
        return l ? std::forward<T>(l) : r.generator();
    }

}false_if;

右辺の評価を遅らせるためにfunctionで受け取るように変更

使い方

main.cpp
int main()
{
    //生ポインタ
    int* a = nullptr;
    a = a | false_if([] {return new int(5); });

    //スマートポインタ
    std::unique_ptr<int> b;
    b = std::move(b) | false_if([] {return std::make_unique<int>(5); });

    //optional
    std::optional<int> c;
    c = c | false_if([] {return 5; });


    std::cout << *a << *b << *c << std::endl;
    return 0;
}

結論

普通にifなり3項演算子でいい気がする