std ::转换为任意容器 [英] std::transform to arbitrary container

查看:47
本文介绍了std ::转换为任意容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个通用函数,该函数接收值为 [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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆