模板类型的约束
Constraints on template types
假设,我想在C++中实现一个通用的高阶Map
函数。 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
也可以采用分配器
相关文章:
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 函数作为模板参数,是否对返回类型强制约束
- 如果原型是本地的,则使用流 I/O C++类型约束将失败
- 约束类模板函数以接受特定的 POD 类型
- TS 概念类型名约束
- 如何在带有约束 (C++) 的函数中使用泛型类型
- 文本类类型成员函数约束
- 如何约束参数类型以仅允许 std::initializer_list<size_t> 或 std::array<size_t, N>?
- 约束类型模板参数仅对特定模板进行实例化
- 为白名单类型约束模板函数的更好方法,SFINAE
- 作为模板参数的可调用类型上的C++约束
- 模板类型的约束
- 如何将类型约束和隐式转换与C++11通用引用相结合?
- c++调用约定是否受标准约束,因为在声明fn时不需要定义函数的返回类型
- 为什么std::copy_if签名不约束谓词类型
- 需要关于c++ v11中类模板中的类型约束设计的建议