gpt4 book ai didi

c++ - 编译器不推导出模板参数(map std::vector -> std::vector)

转载 作者:可可西里 更新时间:2023-11-01 16:29:49 26 4
gpt4 key购买 nike

我有以下模板。

template<typename T, typename U>
std::vector<U> map(const std::vector<T> &v, std::function<U(const T&)> f) {
std::vector<U> res;
res.reserve(v.size());
std::transform(std::begin(v), std::end(v), std::end(res), f);
return res;
}

当我在我的代码中使用它时,我指定了模板参数。为什么编译器不能为我推断出这个?我必须如何更改我的模板定义才能使其正常工作?

vector<int> numbers = { 1, 3, 5 };

// vector<string> strings = map(numbers, [] (int x) { return string(x,'X'); });

vector<string> strings = map<int, string>(numbers, [] (int x) { return string(x,'X'); });

可运行代码:http://ideone.com/FjGnxd

本题原代码出处:The std::transform-like function that returns transformed container

最佳答案

您的函数需要一个 std::function 参数,但您却用 lambda 表达式调用它。两者不是同一类型。 lambda 可转换std::function,但模板参数推导需要精确匹配且不考虑用户定义的转换。因此演绎失败。

如果您实际上将 std::function 传递给 map(),则推导确实有效。

std::function<string(int const&)> fn = [] (int x) { return string(x,'X'); };
vector<string> strings = map(numbers, fn);

Live demo


避免必须指定模板参数的一种可能的解决方法是修改函数以接受任何类型的可调用对象,而不是 std::function 对象。

template<typename T, typename Func>
std::vector<typename std::result_of<Func(T)>::type>
map(const std::vector<T> &v, Func f) {
// ...
}

相同想法的另一个版本,使用 decltypedeclval 而不是 result_of

template<typename T, typename Func>
std::vector<decltype(std::declval<Func>()(std::declval<T>()))>
map(const std::vector<T> &v, Func f) {
// ...
}

最后,使用尾随返回类型

template<typename T, typename Func>
auto map(const std::vector<T> &v, Func f)
-> std::vector<decltype(f(v[0]))> {
// ...
}

Live demo

关于c++ - 编译器不推导出模板参数(map std::vector -> std::vector),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26665152/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com