我想有一个模板函数,其中包含一个vector<T> v
和一个函数op,将T
映射到vector<U>
,并希望将应用{{1} }到f
的每个元素向量,以返回v
= [op(v [0])的元素,op(v [1])的元素...]。
我发现一个可行的选择是在函数中添加一个示例以允许模板推导:
vector<U>
但是自然地,我只想使用两个参数来产生相同的结果。
我的尝试[用{{1}代替template <typename Container>
Container& concat(Container& c1, Container const& c2) {
c1.insert(end(c1), begin(c2), end(c2));
return c1;
}
template <typename Container, typename UnaryOperation, typename U>
inline auto to_vec_from_vectors(Container& c, UnaryOperation&& op, U& ex)
-> std::vector<U> {
std::vector<U> v;
for (auto& e : c) {
std::vector<U> opv = op(e);
concat(v, opv);
}
return v;
}
]:
U
不幸的是,这没有编译。我还担心如果op是复杂方法会浪费时间。
这给了:
decltype(*std::begin(op(*std::begin(c))))
... 所以它似乎与'const'有关。
将如何更正此变体?有更好的选择吗?
答案 0 :(得分:5)
解引用容器迭代器会产生一个引用(如果容器是const,则为const引用),这就是为什么decltype(*std::begin(op(*std::begin(c))))
根据编译器错误产生const U&
的原因(而不是U
)。
您可以通过以下方法解决此问题:用std::remove_reference再次删除引用(或者,如果您也要删除const
和volatile
,std::remove_cvref),或者仅向向量询问其实际存储的内容:
decltype(*std::begin(op(*std::begin(c))))
-> typename decltype(op(*std::begin(c)))::value_type
我已经继续并删除了不需要的U& ex
参数。
template <typename Container, typename UnaryOperation>
inline auto to_vec_from_vectors(Container& c, UnaryOperation&& op)
-> std::vector<typename decltype(op(*std::begin(c)))::value_type> {
std::vector<typename decltype(op(*std::begin(c)))::value_type> v;
for (auto& e : c) {
std::vector<typename decltype(op(*std::begin(c)))::value_type> opv = op(e);
concat(v, opv);
}
return v;
}
您也可以通过命名decltype
来避免三次重复:
template <typename Container, typename UnaryOperation>
using applied_op_t = typename decltype(std::declval<UnaryOperation>()(*std::begin(std::declval<Container>())))::value_type;