将重载函数和参数传递给模板函数

Passing overloaded function and args to template function

我想将两个重载的 fun() 发送到一个处理它们及其参数的模板。这是我目前的尝试:

#include <vector>
#include <iostream>

using namespace std;

class Demo
{};

template<typename Function, typename... Args>
void call(Function func(Args...), Args &&...args)
{
    func(forward<Args>(args)...);       // execute function with args
}

void fun(int first, int second, int third)
{
    cout << "fun with ints\n";
}

void fun(Demo &&dem1, Demo &&dem2)      // adding overload causes the ambiguity
{
    cout << "fun with Demos\n";
}

int main()
{
    call(fun, 1, 2, 3);  
                   
    call(fun, Demo{}, Demo{});     
}

编译器抱怨无法为 main() 中的调用找到匹配的函数:

main.cc: In function ‘int main()’:
main.cc:27:22: error: no matching function for call to ‘call(<unresolved overloaded function type>, int, int, int)’
   27 |     call(fun, 1, 2, 3);
      |                      ^
main.cc:10:6: note: candidate: ‘template<class Function, class ... Args> void call(Function (*)(Args ...), Args&& ...)’
   10 | void call(Function func(Args...), Args &&...args)
      |      ^~~~
main.cc:10:6: note:   template argument deduction/substitution failed:
main.cc:27:22: note:   couldn’t deduce template parameter ‘Function’
   27 |     call(fun, 1, 2, 3);
      |                      ^
main.cc:29:29: error: no matching function for call to ‘call(<unresolved overloaded function type>, Demo, Demo)’
   29 |     call(fun, Demo{}, Demo{});
      |                             ^
main.cc:10:6: note: candidate: ‘template<class Function, class ... Args> void call(Function (*)(Args ...), Args&& ...)’
   10 | void call(Function func(Args...), Args &&...args)
      |      ^~~~
main.cc:10:6: note:   template argument deduction/substitution failed:
main.cc:29:29: note:   couldn’t deduce template parameter ‘Function’
   29 |     call(fun, Demo{}, Demo{});
      |                        

如果有任何想法可以解决这个难题,我们将不胜感激! (C++ overloaded function as template argument 处的解决方案没有解决我的问题,因为我无法更改在 main() 中调用 call() 的方式)

编译错误的原因是编译器不知道你实际要使用哪个fun重载。

要解决此错误,您只需将函数参数转换为正确的重载,例如:

int main()
{
    call( static_cast< void(*)(int, int, int) >( fun ), 1, 2, 3 );  

    call( static_cast< void(*)(Demo&&, Demo&&) >( fun ), Demo{}, Demo{} );

    return 0;
}

仅供参考,您的call函数试图做的事情实际上是由标准定义的。它是 std::invoke 函数,它符合 C++17 标准。