我正在尝试弄乱模板,但是我很新。调用此函数时:
template <typename A, typename B, template<typename> typename Traversable,
typename Fn>
auto map(const Traversable<A>& vec, Fn&& fn)
{
Traversable<B> res{};
for (A e : vec)
res.push_back(fn(e));
return res;
}
像这样:
vector<int> numbers { 1,2,3,4,5 };
auto numbers_times_two = map(numbers, [](auto a) { return a * 2; });
我得到一个模棱两可的错误:
Inferred conflicting substitutions for template parameter Traversable (std::vector and std::_Vector_alloc)
如我所见,编译器不知道是推论vector
还是Traversable
参数的超类。
在未明确指定模板参数的情况下,对map
进行调用的最佳方法是 进行编译?适用于其他forward_list
和array
等其他可迭代对象的解决方案。
在这种情况下,是否有通用的解决方案来推导最具体的类而不是超类?
编辑:这仅在VS2017编译器中发生,但在g ++上有效。
因此,在使用Jarod42s answer之后,我创建了自己的容器类,只是为了查看错误是否仍然发生:
template <typename T>
class NewVec : public vector<T>
{
public:
NewVec(initializer_list<T> il): vector<T>(il) {}
};
int main()
{
NewVec<int> nv{ 1,2,3,4,5 };
auto doubled = map(nv, [](auto a) { return a * 2; });
}
现在,该调用编译没有问题。但是vector
和forward_list
仍然会产生上述错误。
答案 0 :(得分:1)
您可以使用:
template <template <typename, typename...> class Container, typename T, typename F>
auto map(const Container<T>& vec, F&& f)
{
using RetType = std::decay_t<decltype(f(*vec.begin()))>;
Container<RetType> res{};
for (auto&& e : vec)
res.push_back(f(e));
return res;
}
所以所有类型都是可推论的。
理想情况下,我什至会删除T
并使用rebind::other
作为分配器提供的内容,但是容器不提供它。