gpt4 book ai didi

c++ - 模板类型的限制

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:54:22 28 4
gpt4 key购买 nike

假设,我想实现一个通用的高阶 Map C++中的函数。 Map应该采用一个容器和一个转换函数并返回一个相同类型的容器,但可能包含不同类型的项目。

我们以vector为例例如:

template <typename InT, typename OutT, typename Tr>
vector<OutT> Map(vector<InT> cont, Tr tr)
{
OutCont out(cont.size());
auto oit = out.begin();
for (auto it = cont.cbegin(); it != cont.cend(); ++it, ++ot)
{
*oit = tr(*it);
}
}

我想这样使用:

vector<int> v(10);
std::iota(v.begin(), v.end(), 0);
auto x = Map(v, [](int x) -> int {return x * 2;});

这在 VC++ 2012 中失败,出现以下错误:

error C2783: 'std::vector<OutT> Map(std::vector<_Ty>,Tr)' : could not deduce template argument for 'OutT'   

在我看来,编译器拥有所有必要的信息,因为我在 lambda 中明确定义了返回类型。有解决办法吗?

上面的例子使用了vector .有没有办法使用泛型类型,使输入和输出类型相同?例如,如果我有一个定义为 vector<string> 的输入容器和转换函数 tr(string a) -> int , 那么我的目标是让编译器确定输出类型为 vector<int> .这是我想要实现的伪代码:

template <typename Cont<InT>, typename Cont<OutT>, typename Tr<InT, OutT>>
Cont<OutT> Map(Cont<InT> cont, Tr<InT, OutT> tr)
{
// Implementation
}

最佳答案

你可以这样写:

template <typename InT, typename Tr>
auto Map(std::vector<InT> cont, Tr tr) -> std::vector<decltype(tr(cont[0]))>
{
std::vector<decltype(tr(cont[0]))> out(cont.size());
auto oit = out.begin();
for (auto it = cont.cbegin(); it != cont.cend(); ++it, ++oit)
{
*oit = tr(*it);
}
return out;
}

推导出类型。

[编辑]对于具有更多容器的更通用的函数:

template <template<typename, typename...> class Container, typename InT, typename Tr, typename... Args>
auto Map(const Container<InT, Args...>& cont, Tr tr) -> Container<decltype(tr(cont[0])), Args...>
{
Container<decltype(tr(cont[0])), Args...> out(cont.size());
auto oit = out.begin();
for (auto it = cont.cbegin(); it != cont.cend(); ++it, ++oit)
{
*oit = tr(*it);
}
return out;
}

注意 typename... 是必需的,因为 std::vector 也可以采用分配器

关于c++ - 模板类型的限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19566629/

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