带有很少参数的模板函数的推导

sov*_*sti 1 c++ templates function-templates template-argument-deduction c++17

我有几个模板函数的实例。它们中的每一个都按顺序执行每个给定的 lambda,并附带特定的消息。当我使用一个 lambda 执行此操作时,一切正常,但是当我尝试添加多个 lambda 时,我得到

note: candidate template ignored: deduced conflicting types for parameter 'Task'
Run Code Online (Sandbox Code Playgroud)

来自铿锵。这是我的代码:


template <class Task> void doTasks(Task task1)  // works fine
{  
    if (std::__is_invocable<Task>::value) 
    {
        std::cout << "doing first task" << endl;
        task1;
    }
}

template <class Task>
void doTasks(Task task1, Task task2) // deduced conflicting types
{ 
    if (std::__is_invocable<Task>::value) 
    {
        std::cout << "doing first task" << endl;
        task1();
        std::cout << "doing second task" << endl;
        task2();
    }
}


int main()
{
    doTasks([&] (){std::cout << "1" << endl;}); 

    doTasks([&] (){std::cout << "1" << endl;},
            [&] (){std::cout << "2" << endl;}); 
  
    return 0; 
}
Run Code Online (Sandbox Code Playgroud)

它出什么问题了?我该如何处理我的问题?

抱歉,如果这是一个愚蠢的问题,我是 C++ 的初学者,可能不理解一些模板的细微差别。

JeJ*_*eJo 6

尽管两个传递的 lambda 执行相同或看起来相似,但它们具有完全不同的类型。因此,您需要在doTasks.

简单的解决方法是为两个 lambda 提供模板参数

template <class T1, class T2>
void doTasks(T1 task1, T2 task2)
{
  // ...
}
Run Code Online (Sandbox Code Playgroud)

否则,使用可变参数模板函数和折叠表达式,您可以执行以下操作:

#include <type_traits> // std::conjunction_v, std::is_invocable

template <class... Ts>
void doTasks(Ts&&... lmds) {
    if (std::conjunction_v<std::is_invocable<Ts>...>) // maybe if constexpr
    {
        (lmds(), ...);
    }
}
Run Code Online (Sandbox Code Playgroud)

由于参数是可变的,它也适用于单个/任何参数doTasks,因此没有代码重复。

现场演示