我写了一个简单的函数,当在迭代器上使用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);
}
这里可能是什么错误?预先感谢。
答案 0 :(得分: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
)。
答案 1 :(得分:0)
首先:您无法将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)