我有一个(简化的)函数Foo
template<typename It, typename T>
void Foo(It begin, It end, T&& CallBar)
{
CallBar(begin, end);
}
另一个简化的功能吧
template<typename It>
It Bar(It begin, It end)
{
return begin;
}
当我以下列方式调用这两个函数时
std::vector<int> v{ 3, 8, 2, 5, 1, 4, 7, 6 };
Foo(v.begin(), v.end(), Bar);
我收到错误
'declaration':无法推断'identifier'的模板参数
我还需要指定什么来使其编译?
答案 0 :(得分:6)
这里的问题是,由于Bar
是一个功能模板,因此它不知道您想要哪个Bar
。你必须告诉它使用什么版本的Bar
。一种方法是指定模板类型。你可以这样做:
Foo(v.begin(), v.end(), Bar<decltype(v.begin())>);
如果您不想指定模板类型,说实话,有点脆弱,那么我们可以将调用包装在lambda中Bar
。这将允许编译器为我们执行所有类型推导,这更容易维护。例如,如果您更改迭代器类型,则无需更改以前的解决方案。感谢0x499602D2,这将是
Foo(v.begin(),v.end(),[](auto b,auto e){return Bar(b,e);})
答案 1 :(得分:2)
我还需要指定什么来使其编译?
以示例
template<typename It>
void Foo(It begin, It end, It(* CallBar)(It, It))
{
CallBar(begin, end);
}
答案 2 :(得分:2)
您可以使用template templates来帮助解决此问题。据我所知,它要求您将Bar
函数包装在仿函数中。通过首先放置仿函数模板参数,您可以指定它并让迭代器类型被推导出来。
#include <vector>
// T is a type that takes a 'class' template argument
template<template<class> class T, class It>
void Foo(It begin, It end)
{
T<It>()(begin, end);
}
template<typename It>
struct Bar
{
It operator()(It begin, It end)
{
return begin;
}
};
int main()
{
std::vector<int> v{ 3, 8, 2, 5, 1, 4, 7, 6 };
Foo<Bar>(v.begin(), v.end());
return 0;
}