错误:不匹配的类型:<function> 和 <lambda>

Posted

技术标签:

【中文标题】错误:不匹配的类型:<function> 和 <lambda>【英文标题】:error: mismatched types: <function> and <lambda> 【发布时间】:2019-09-19 14:18:58 【问题描述】:

我写了一个简单的函数,当在迭代器上使用std::for_each 时,它给了我一个索引。函数如下:

template<typename It, typename I = std::size_t>
void for_each_indexed(It begin,
                      It end,
                      void l(typename std::iterator_traits<It>::value_type, I),
                      I counter = 0) 
    std::for_each(begin, end,
        [&counter, &l](typename std::iterator_traits<It>::value_type value) 
            l(value, counter);
            counter++;
        );
;

我的问题是,当我将 lambda 传递给此函数时,我收到如下错误:

test.cpp:40:6: error: no matching function for call to ‘for_each_indexed(std::__cxx11::
basic_string<char>::iterator, std::__cxx11::basic_string<char>::iterator, crossOutChar(
std::__cxx11::string&, char)::<lambda(char, size_t)>)’
     );
      ^
test.cpp:18:6: note: candidate: ‘template<class It, class I> void for_each_indexed(It, 
It, void (*)(typename std::iterator_traits<_Iter>::value_type, I), I)’
 void for_each_indexed(It begin,
      ^~~~~~~~~~~~~~~~
test.cpp:18:6: note:   template argument deduction/substitution failed:
test.cpp:40:6: note:   mismatched types ‘void (*)(typename std::iterator_traits<_Iter>:
:value_type, I)’ and ‘crossOutChar(std::__cxx11::string&, char)::<lambda(char, size_t)’
     );
      ^

以下编译并运行:

void process(char c, size_t i) 

void crossOutChar(std::string &s, char c) 
    for_each_indexed(s.begin(), s.end(), process);

但以下不是:

void
crossOutChar(std::string &s, char c) 
    auto process = [c, &s](char c2, size_t i) 
      if (c == c2) 
        s[i] = '*';
      
    ;

    for_each_indexed(s.begin(), s.end(), process);

这里可能有什么错误?提前致谢。

【问题讨论】:

【参考方案1】:

捕获的 lambda 不能转换为指向函数的指针。您可以将函数原型更改为类似

template<class F, typename It, typename I = std::size_t>
void for_each_indexed(It begin,
                      It end,
                      F &&l,
                      I counter = 0)

附带说明,整数对象(此处为counter)更适合按值捕获。

【讨论】:

【参考方案2】:

首先:您不能将 lambda 表达式转换为函数指针,因为它会捕获。

要处理您引用的两种情况,您必须使用std::function。但是,由于转换为std::function,即使您设置了默认参数,编译器也将无法推断出I。然后,您有一些选择:

显式设置std::size_t:

std::function<void(typename std::iterator_traits<It>::value_type, std::size_t)> l

或者为函数创建另一个模板参数:

template<typename It, typename F, typename I = std::size_t>
void for_each_indexed(It begin,
                      It end,
                      F&& l,
                      I counter = 0)

【讨论】:

可以强制转换无捕获的 lambda。

以上是关于错误:不匹配的类型:<function> 和 <lambda>的主要内容,如果未能解决你的问题,请参考以下文章

Spark 类型不匹配:无法从 DataFrame 转换为 Dataset<Row>

匿名的define()模块不匹配

java.lang.String 和 String 之间的类型不匹配错误

类型不匹配。必需:FirebaseRecyclerAdapter<ChatObject, ChatVoiceViewHolders>?成立:

错误:'operator<<' 不匹配(操作数类型为'std::ostream' aka'std::basic_ostream<char>' 和'std::_List_iter

Flink:PageRank 类型不匹配错误