扣除模板功能很少

发布于 2025-02-10 15:30:34 字数 1101 浏览 0 评论 0原文

我几乎没有一个模板功能的实例。他们每个人都依次执行每个给定的lambdas,并伴随着特定的消息。当我用一个lambda做到这一点时,一切都很好,但是当我尝试添加多个lambda时,我会

note: candidate template ignored: deduced conflicting types for parameter 'Task'

clang 中获得。这是我的代码:


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; 
}

有什么问题?我该如何处理我的问题?

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

I have few instances of one template function. Each of them sequentially executes each of given lambdas, accompanying them with specific messages. When I do that with one lambda, everything works fine, but when I try to add more than one, I get

note: candidate template ignored: deduced conflicting types for parameter 'Task'

From clang. Here is my code:


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; 
}

What's wrong with it? How can I deal with my problem?

Sorry if it's a stupid question, I'm some kind of beginner in C++ and may not understand some template nuances.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

比忠 2025-02-17 15:30:34

即使两者通过了Lambdas相同或看起来相似,但它们具有完全不同的类型。因此,您需要在Dotasks中使用两种不同的模板类型。

简单修复程序是

template <class T1, class T2>
void doTasks(T1 task1, T2 task2)
{
  // ...
}

使用variadic模板函数和 fold Expression < /a>,您可以做类似的事情:

#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(), ...);
    }
}

由于参数为variadic,因此它也适用于dotasks的单个/任何参数,因此无代码重复。

live demo

Even though the two passed lambdas does the same or looks similar, they have completely different types. Hence, you need two different template types there in the doTasks.

Easy fix is providing the template parameter for two lambdas

template <class T1, class T2>
void doTasks(T1 task1, T2 task2)
{
  // ...
}

otherwise, using the variadic template function and fold expression, you could do something like:

#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(), ...);
    }
}

Since the argument is variadic, it will also work for the single/ any arguments of doTasks and hence no code duplication.

Live demo

旧街凉风 2025-02-17 15:30:34

Lambdas的类型不同。您需要为第二个添加另一个模板参数:

#include <type_traits> // for the proper `std::invocable`

template <class Task, class AnotherTask>
void doTasks(Task task1, AnotherTask task2) {
    if constexpr (std::is_invocable_v<Task> && std::is_invocable_v<AnotherTask>) {
        std::cout << "doing first task\n";
        task1();
        std::cout << "doing second task\n";
        task2();
    }
}

注意:由于是C ++ 17,也可以使用 constexpr if 仅在编译时处理 。

demo

The lambdas are of different types. You need to add another template parameter for the second one:

#include <type_traits> // for the proper `std::invocable`

template <class Task, class AnotherTask>
void doTasks(Task task1, AnotherTask task2) {
    if constexpr (std::is_invocable_v<Task> && std::is_invocable_v<AnotherTask>) {
        std::cout << "doing first task\n";
        task1();
        std::cout << "doing second task\n";
        task2();
    }
}

Note: Since it's C++17, you can also use constexpr if to deal with the if at compile time only.

Demo

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文