如何在C++中从std::函数签名构造无操作回调?

ovfsdjhp  于 2023-04-01  发布在  其他
关注(0)|答案(4)|浏览(94)

我有一些回调定义,如:

using TSomeCallback = std::function<ReturnType(Type1, Type2, Type3, …)>;

我也有一些方法接受这个回调作为参数:

void SetCallback(TSomeCallback);

我只想定义一个模板,直接从TSomeCallback示例化no-op callback

void SetCallback(TSomeCallback = GetNoopCallback<TSomeCallback>());  // or
void SetCallback(TSomeCallback = GetNoopCallback(TSomeCallback()));  // or any other way.

我找到了this答案-它很好,但我不知道如何改进它以达到我的目的。

dauxcl2d

dauxcl2d1#

你可以这样做

void SetCallback(TSomeCallback = [](auto...){});

但我建议你

void SetCallback(TSomeCallback = {})

然后检查回调函数是否为非空。或者如果你不想被回调的话,可以不提供默认参数,也可以不调用SetCallback

7kqas0il

7kqas0il2#

你可以使用lambda来构造一个什么都不做的std::function< ... >。假设返回类型是void,那么这样就可以了:

#include <functional>
#include <string>
using namespace std;
     
using TSomeCallback = std::function<void(int,double,int)>;
     
int main() {
    TSomeCallback tc = [](auto...){};
    tc(42,12.0,42);
}
pxy2qtax

pxy2qtax3#

您可以为void实现GetNoopCallback-返回如下函数:

template <class F>
F GetNoopCallback() {
    return [](auto&&...){};
}

然后:

void SetCallback(TSomeCallback = GetNoopCallback<TSomeCallback>());
ie3xauqp

ie3xauqp4#

#include <type_traits>

template <typename result>
requires (std::is_void_v<result> ||
          std::is_default_costructible_v<result>)
constexpr auto return_default = [] (auto&& ...)
noexcept (std::is_void_v<result> ||
          std::is_nothrow_default_costructible_v<result>)
{
    if  constexpr (std::is_void_v<result>)
        return;
    else
        return result {};
};

现在只需要将模板变量强制转换或使用为右值:

std::function<void(int)> f1 = return_default<void>;
auto f2 = std::function<A(B,C)>{return_default<A>};

您可以进一步消除对返回类型的需求:

struct any_function_default{
    template<typename result, typname ... args>
    requires (std::is_void_v<result> ||
              std::is_default_costructible_v<result>)
    constexpr operator std::function<result(args ...)> () const {
        return [] (auto&& ...) {
               if  constexpr (std::is_void_v<result>)
                   return;
               else
                   return result {};
        };
    };
};

现在使用any_function_default作为函数的通用默认值:

std::function<void(int)> f1 = any_function_default{};
auto f2 = std::function<A(B,C)> { any_function_default{} };

相关问题