9

ジェネリックラムダは「置換の失敗はエラーではない」ルールを利用できますか? 例

auto gL = 
    [](auto&& func, auto&& param1, auto&&... params) 
        -> enable_if_t< is_integral<
            std::decay_t<decltype(param1)>
        >::value>
    {
        // ...
    };

auto gL =  
     [](auto&& func, auto&& param1, auto&&... params) 
        -> enable_if_t< !is_integral<
            std::decay_t<decltype(param1)>
        >::value>
    {
        // ...
    };

これを言語に含めるための回避策や計画はありますか? また、ジェネリックラムダは内部でテンプレート化された関数オブジェクトであるため、これができないのは少し奇妙ではありませんか?

4

3 に答える 3

2

ジェネリック ラムダは本体を 1 つしか持てないため、ここでは SFINAE はあまり役に立ちません。

1 つの解決策は、結果を格納できるクラスに呼び出しをパッケージ化し、void戻り値の型に特化しvoidて、ラムダから特別な処理をカプセル化することです。スレッド ライブラリ機能を使用すると、オーバーヘッドがほとんどなく、これを行うことができます。

auto gL = 
    [](auto&& func, auto&&... params)
    {
        // start a timer
        using Ret = decltype(std::forward<decltype(func)>(func)(
            std::forward<decltype(params)>(params)...));
        std::packaged_task<Ret()> task{[&]{
            return std::forward<decltype(func)>(func)(
                std::forward<decltype(params)>(params)...); }};
        auto fut = task.get_future();
        task();
        // stop timer and print elapsed time
        return fut.get(); 
    };

packaged_taskとのオーバーヘッドを避けたい場合はfuture、独自のバージョンを簡単に作成できます。

template<class T>
struct Result
{
    template<class F, class... A> Result(F&& f, A&&... args)
        : t{std::forward<F>(f)(std::forward<A>(args)...)} {}
    T t;
    T&& get() { return std::move(t); }
};
template<>
struct Result<void>
{
    template<class F, class... A> Result(F&& f, A&&... args)
        { std::forward<F>(f)(std::forward<A>(args)...); }
    void get() {}
};

auto gL = 
    [](auto&& func, auto&&... params)
    {
        // start a timer
        using Ret = decltype(std::forward<decltype(func)>(func)(
            std::forward<decltype(params)>(params)...));
        Result<Ret> k{std::forward<decltype(func)>(func),
            std::forward<decltype(params)>(params)...};
        // stop timer and print elapsed time
        return k.get(); 
    };
于 2015-07-06T20:09:26.010 に答える