分配值或回调函数的C ++重载模板

All*_*nus 7 c++ templates c++17

尝试做类似...

template <class T>
struct Wrapper
{
    template <class U>
    void set(const U& u) { myT = u; }

    template <class F>
    void set(F f) { myT = f(); }

    T myT;
};
Run Code Online (Sandbox Code Playgroud)

我知道我需要在这里使用SFINAE,但是如何区分回调参数和值参数呢?可以安全地假定一个值不能用作回调。

我试着enable_ifis_function, result_ofinvoke_resultis_invocable,和其他人,但没有它的作品的权利。可能吗

Evg*_*Evg 8

您可以在不使用SFINAE的情况下进行操作:

template<class U>
void set(const U& u) { 
    if constexpr (std::is_invocable_v<U>)
        myT = u();
    else
        myT = u;
}
Run Code Online (Sandbox Code Playgroud)

或者以更通用的方式:

template<class U>
void set(U&& u) { 
    if constexpr (std::is_invocable_v<U>)
        myT = std::forward<U>(u)();
    else
        myT = std::forward<U>(u);
}
Run Code Online (Sandbox Code Playgroud)

  • 因为更好的编译时间,所以比SFINAE更喜欢constexpr (2认同)

son*_*yao 7

是的,您可以在std::is_invocable(自C ++ 17起)的帮助下应用SFINAE 。

template <class U>
std::enable_if_t<!std::is_invocable_v<U>> set(const U& u) { myT = u; }

template <class F>
std::enable_if_t<std::is_invocable_v<F>> set(F f) { myT = f(); }
Run Code Online (Sandbox Code Playgroud)

生活