2015-11-08 23 views
7

私は後で呼び出すことができる関数のラッパーとして動作ラムダ生成する機能を持っている:テンプレート引数がnoexcept関数であるかどうかをどのように検出できますか?

template <typename F, typename... FArgs> 
auto make_lambda(F&& f, FArgs&&... f_args) 
{ 
    return [&]() -> std::result_of_t<F(FArgs...)> 
    { 
     return std::forward<F>(f)(std::forward<FArgs>(f_args)...); 
    }; 
} 

私は、引数fnoexceptですので、私の関数の戻り値は、希望したときに返さラムダnoexceptをしたいのですが次のようになります。

return [&]() noexcept(is_noexcept<decltype(f)>::value) 
    -> std::result_of_t<F(FArgs...)> 
{ 
    return std::forward<F>(f)(std::forward<FArgs>(f_args)...); 
}; 

私の試み:

#include <type_traits> 

void f() {} 
void g() noexcept {} 

template <typename F, typename... Args> 
struct is_noexcept : std::false_type {}; 

template <typename F, typename... Args> 
struct is_noexcept<F(Args...) noexcept> : std::true_type {}; 

int main() 
{ 
    bool constexpr func_test_a{ is_noexcept<decltype(f)>::value }; // true 
    bool constexpr func_test_b{ is_noexcept<decltype(g)>::value }; // true 
} 

しかし、TE stは常にtrueを返します。私は何が欠けていますか?誰でもこの問題の解決法を提供できますか?

答えて

9

http://en.cppreference.com/w/cpp/language/noexcept_spec

noexcept仕様は、関数型の一部ではありません。 ( C++ 17まで)。

noexcept指定子が関数の型の一部ではないため、テンプレートの控除では正しい結果が得られません。テンプレート型の控除はC++ 17までは動作しません。関数がnoexceptであるかどうかを検出する私の方法は、this answerのようにC++ 17で有効です。

7

noexcept operatorは式を取り、その式がnoexceptの場合はtrueを生成します。

未テストですが、これはご使用のケースでうまくいく可能性があります。より

return [&]() noexcept(noexcept(std::forward<F>(f)(std::forward<FArgs>(f_args)...))) 
    -> std::result_of_t<F(FArgs...)> 
{ 
    return std::forward<F>(f)(std::forward<FArgs>(f_args)...); 
}; 
+0

私が試した最初のことでしたが、 'f()'と 'g()'に 'true'を返します。 – user2296177

+0

私の答えに記載されているように、これはC++で有効な答えです17。 – user2296177

関連する問題