std::is_invocable<...> 检查成员函数

non*_*741 3 c++ std visual-c++ c++17

以下代码正确确定何时Writer( t )可以调用给定的T.

template <typename T>
inline void Process( const T& t )
{
    if constexpr ( std::is_invocable<decltype(Writer), const T&>::value )
    {
        Writer( t );
    }
    else { //... }
}
Run Code Online (Sandbox Code Playgroud)

但我只能让它operator()在 Writer 中定义为例如

class Writer
{
 public:
    operator()( const int& )
    {
        \\...
    }
}
Run Code Online (Sandbox Code Playgroud)

如何对成员函数进行相同的检查,即检查该函数是否存在,例如Write(...)in

class Writer
{
public:
    inline void Write( const int& t )
    {
    }
};

class Archive
{

public:

    template <typename T>
    inline void Process( const T& t )
    {
        //check if Writer can handle T
        if constexpr ( std::is_invocable_v<decltype( ???&Writer::Write??? ), ???, const T&> )
        {
            TheWriter.Write( t );
            std::cout << "found";
        }
        else
        {    
            std::cout << "not found";
        }
    }

    Writer TheWriter;

};
Run Code Online (Sandbox Code Playgroud)

我尝试过的每一种可能的组合都会导致编译器错误Writer.Write甚至.Writer::Writedecltype&if constexprfatal error C1001

这是在带有 /std:c++17 的 Visual Studio 2017 MSVC_1916 上。

cig*_*ien 8

您可以像这样检查成员函数:

template <typename T>
inline void Process( const T& t )
{
    if constexpr ( std::is_invocable_v<decltype(&Writer::Write), Writer&, T const &> )    
    {
        Writer{}.Write(t);
    }
    else 
    { 
        //... 
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个工作演示。感谢@aschepler 指出原始片段中的错误。

  • 我认为`std::is_invocable_v&lt;decltype(&amp;Writer::Write), Writer&amp;, const T&amp;&gt;`。指向非静态成员函数的指针需要一个对象来调用该函数,并且“std::invoke”和朋友将此类类型/对象视为第一个参数/参数。 (7认同)