【问题标题】:Why does using the default template parameter for a function also used in a lambda parameter not work为什么对同样用于 lambda 参数的函数使用默认模板参数不起作用
【发布时间】:2020-07-14 11:39:05
【问题描述】:

采用以下 c++ 代码,编译良好(gcc 10.1.0):-

#include <iostream>
#include <string>
#include <functional>

template <class T = std::string>
void foo(T src, std::function<void(T&& t)> completionFn)
{
    completionFn(std::move(src));
}

int main(int argc, char *argv[])
{
    foo<std::string>("hello", [] (auto && t) {
        std::cout << t << std::endl;
    });

    return 0;
}

如果我修改 main 函数以删除对“foo”的调用中的模板参数,即使我有一个默认模板参数,它也不再编译,我无法找出原因。

int main(int argc, char *argv[])
{
    foo<>("hello", [] (auto && t) {
        std::cout << t << std::endl;
    });

    return 0;
}

我可能遗漏了一些明显的东西。

这是编译器的输出:-

src/scanner_test.cpp: In function ‘int main(int, char**)’:
src/scanner_test.cpp:19:6: error: no matching function for call to ‘foo(const char [6], main(int, char**)::<lambda(auto:11&&)>)’
   19 |     });
      |      ^
src/scanner_test.cpp:10:6: note: candidate: ‘template<class T> void foo(T, std::function<void(T&&)>)’
   10 | void foo(T src, std::function<void(T&& t)> completionFn)
      |      ^~~
src/scanner_test.cpp:10:6: note:   template argument deduction/substitution failed:
src/scanner_test.cpp:19:6: note:   ‘main(int, char**)::<lambda(auto:11&&)>’ is not derived from ‘std::function<void(T&&)>’
   19 |     });

我错过了什么?谢谢!抱歉,如果这是一个愚蠢的问题。

【问题讨论】:

    标签: c++ templates lambda


    【解决方案1】:

    仅当模板无法从上下文中确定时才使用默认模板参数。在给定foo&lt;&gt;("hello", ...) 的上下文中,模板 T 被确定为const char [6](如错误消息中所示)。对于函数,与函数中的实际参数相关的模板参数总是如此。

    您可能正在寻找的解决方案是:

    #include <iostream>
    #include <string>
    #include <functional>
    
    template <class T>
    void foo(T src, std::function<void(std::string&& t)> completionFn)
    {
        //NOTE cast here to std::string, ensures we always have an std::string
        completionFn(std::move((std::string&)src));
    }
    
    int main(int argc, char *argv[])
    {
        foo("hello", [] (std::string&& t) {
            std::cout << t << std::endl;
        });
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-03
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多