限制函数模板仅用于成员函数

Ale*_*lex 1 c++ templates c++11

我正在 C++11 中工作,并有以下可以编译的代码。但问题是func下面示例中的函数也可以使用 a std::function、lambda、函数指针等来调用。

相反,我希望func只能通过指向任何类的非静态成员函数的指针来调用它。也就是说,我想限制这个函数只有成员函数指针。

template <typename Callable, typename... Args> void func(Callable&& callable, Args&&... args)
{

}
struct Test
{
    int someMember(int x) 
    { 
        return x; 
    }
};
void g(int, int, int) 
{

}
int main()
{
    func(g, 1, 1, 1);     //this works currently but it should be rejected in the modified program
    func([](int){}, 42);  //this works currently but it should be rejected in the modified program 
    
    Test test;
    func(&Test::someMember, test, 1);// this works currently and should work in the modified version
}
Run Code Online (Sandbox Code Playgroud)

正如我们在上面的程序中看到的,所有的调用都func有效。但我希望只有该呼叫func(&Test::someMember, test, 1);应该有效,而其他两个呼叫应该被拒绝。

那么我怎样才能实现这一目标。也许有一种方法可以使用 SFINAE 或其他元编程技术。

Nel*_*eal 5

我认为static_assert(with std::is_member_function_pointer) 是适合这种情况的完美工具。无需更改 的签名func,并且错误消息可以是您想要的任何内容,因此它比替换失败等更清晰。

要拨打电话callable,您可以使用std::mem_fn.

template <typename Callable, typename... Args>
void func(Callable callable, Args&&... args)
{
    static_assert(std::is_member_function_pointer<Callable>::value, "callable must be a member function");

    std::mem_fn(callable)(args...);
}
Run Code Online (Sandbox Code Playgroud)

演示