std ::转换为任意容器 [英] std::transform to arbitrary container
问题描述
我想编写一个通用函数,该函数接收值为 [a1,..,an]
的 container1
,并返回另一个值为 [convert(a1),..,convert(an)]
.如果 container2
是 std :: vector
,那么问题就微不足道, std :: transform
正是我想要的.以下函数可以处理任意 container2
和 container1
I want to write universal function that receives container1
with values [a1, .. , an]
and returns another container2
with values [convert(a1), .. , convert(an)]
.
If container2
is std::vector
, the problem is trivial, std::transform
does exactly what I want. The following function can deal with arbitrary container2
and container1
template<class ToType, class FromType>
ToType convert(const FromType& from)
{
std::vector<typename ToType::value_type> tmp;
std::transform(from.begin(), from.end(),
std::back_inserter(tmp),
[](const typename FromType::value_type& f) {
return convert<typename ToType::value_type>(f);
});
return ToType(tmp.begin(), tmp.end());
}
但是它会添加副本.有谁知道如何做得更好?
But it does addition copy. Does anyone know how to do better?
推荐答案
查看此答案以
Check out this answer to Is it possible to write a C++ template to check for a function's existence?. You can use SFINAE to detect if a function of your destination container exists (such as push_back
or insert
) or if an inserter for your container exists (such as inserter
or back_inserter
), and behave accordingly.
另一种方法是创建一个伪造的迭代器:
Another way is to create a fake iterator:
template <class T, class U>
struct ConvertIterator {
typedef T dest_type;
typedef U it_type;
ConvertIterator(U&& val) : iterator(std::forward<U>(val)) {
}
bool operator == (const ConvertIterator &other) const {
return iterator == other.iterator;
}
bool operator != (const ConvertIterator &other) const {
return iterator != other.iterator;
}
dest_type operator * () const {
return convert<dest_type>(*iterator);
}
ConvertIterator<T, U> & operator ++() {
++iterator;
return *this;
}
it_type iterator;
};
然后:
template<class ToType, class FromType>
ToType convert(const FromType& from)
{
typedef ConvertIterator<typename ToType::value_type, decltype(from.begin()) > convert_it;
return ToType(convert_it(from.begin()), convert_it(from.end()));
}
这篇关于std ::转换为任意容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!