c++函数多态性/模板

我的目标是提供三种调用函数的方法listen()。有一个更好的方法吗?(比如使用模板或默认值参数,所以我只能实现一个listen()功能)
我目前的方法

void listen(const int &port,
                 const std::function<void(std::string err)> &f) {
    http_server_.listen(port, [f](std::string err) { f(err); });
}
void listen(const int &port, const std::function<void()> &f) {
    http_server_.listen(port, [f](std::string err) { f(); });
}
void listen(const int &port) {
    http_server_.listen(port, [](std::string err) {});
}

我已经尝试了看起来像的模板方法

template <typename Func> void listen(const int &port, Func f = {}) {
    // do some if-else here.
}

但它不起作用。

回答

IMO 你的方法接近最佳。如果我在写这个,我只会做一些小的改动:

void listen(int port, std::function<void(const std::string &err)> f)
{
    http_server_.listen(port, std::move(f));
}
void listen(int port, std::function<void()> f)
{
    http_server_.listen(port, [f = std::move(f)](const std::string &){f();});
}
void listen(int port)
{
    // Are you sure the lambda is needed? Maybe passing `nullptr` will work.
    http_server_.listen(port, [](const std::string &){});
}

在这里,f = std::move(f)(而不是f)在 lambda 捕获中至少需要 C++14。如果您仅限于 C++11 并且不能这样做,那么您应该改f回由 const 引用传递(在第二个重载中)。


在 C++17 之前,将这些组合成一个函数是不容易的,并且需要更多的样板,而不是它要消除的。

在 C++17 中你可以使用if constexpr,但如果你问我,它仍然只会让事情变得更糟:

template <typename, typename...> struct always_false : std::false_type {};

template <typename F = std::nullptr_t>
void listen(int port, F &&f = nullptr)
{
    if constexpr (std::is_nullptr_v<std::remove_const_t<std::remove_reference_t<F>>>)
    {
        http_server_.listen(port, [](const std::string &) {});
    }
    else
    {
        http_server_.listen(port, [f = std::forward<F>(f)](const std::string &err)
        {
            if constexpr (std::is_invocable_v<const F &, const std::string &>)
                std::invoke(f, err);
            else if constexpr (std::is_invocable_v<const F &>)
                std::invoke(f);
            else
                static_assert(always_false<F>, "The function is invalid.");
        });
    }
}

这不仅需要两倍的输入,还可以防止调用者使用 SFINAE 检查您的函数接受或不接受哪些函数参数。


以上是c++函数多态性/模板的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>