c++ - 定义一个 "vector_cast"模板函数,它可以处理可变数量的嵌套 vector

标签 c++ vector casting nested

例如,我希望能够做这样的事情。

    std::vector<std::vector<int>>     e = {{ 1 },{ 2 }};
    std::vector<std::vector<double>>  q = {{1.5},{2.5}};

    q = vector_cast<double>(e);

但也让 vector_cast 能够处理任意数量的嵌套 vector 。

这是我的尝试。如果您注释掉标记为无效的行,则代码有效。问题是我需要帮助来实现 vector_cast 函数。

#include <iostream>
#include <vector>
#include <algorithm>
#include <type_traits>


//Prints nested vectors
template<typename T1>
std::ostream& operator<<(std::ostream& stream, std::vector<T1> r){
    if(r.size() == 0){
        return stream;
    }
    else{
        stream << "(";
        for(int i = 0; i < r.size(); i++){
            if(i < (r.size() - 1)){
                stream << r[i] << ", ";
            }
            else{
                stream << r[i] << ")";
            }
        }
    }
    return stream;
};

//Adds nested vectors
template <typename T1, typename T2>
struct vector_common_type : std::common_type<T1, T2> { };

template <typename T1, typename T2>
struct vector_common_type<std::vector<T1>, std::vector<T2>> {
    using type = std::vector<typename vector_common_type<T1,T2>::type>;
};

template <typename T1, typename T2,
          typename R = std::vector<typename vector_common_type<T1,T2>::type>>
R operator+(const std::vector<T1>& l, const std::vector<T2>& r)
{
    R ans;
    std::transform(l.begin(),
                   l.begin() + std::min(l.size(), r.size()),
                   r.begin(),
                   std::back_inserter(ans),
                   [](const T1& lhs, const T2& rhs){ return lhs + rhs; });
    return ans;
}

//supposed to cast nested vectors
template <typename T1, typename T2>
struct vector_casting : std::condition<true,T1, T2> { };

template <typename T1, typename T2>
struct vector_casting<std::vector<T1>, std::vector<T2>> {
    using type = std::vector<typename vector_casting<T1,T2>::type>;
};

template <typename T1, typename T2,
          typename R = std::vector<typename vector_casting<std::vector<T1>,T2>::type>>
R vector_cast(const std::vector<T2>& r){
    R l(r.begin(),r.end());
    return l;
};

int main(){
    std::vector<std::vector<int>> e = {{ 1 },{ 1 }};
    std::vector<std::vector<double>> q = {{1.5},{2.5}};

    //This works
    q = q + q;

    //This does not work
    q = e;//<- needs cast, but my vector_cast does not work

    std::cout << q << std::endl;
    return 0;
}

最佳答案

通过 vector 类型检测,您可以:

#include <iostream>
#include <vector>

// is_vector
// =========

namespace Detail {
    template<typename T>
    struct is_vector_test {
        static constexpr bool value = false;
    };


    template<typename ... Types>
    struct is_vector_test<std::vector<Types...>> {
        static constexpr bool value = true;
    };
}

template<typename T>
struct is_vector : Detail::is_vector_test<typename std::decay<T>::type>
{};

// vector_cast
// ===========

namespace Detail
{
    template <typename R, typename U, bool = is_vector<U>::value>
    struct vector_cast_implementation;

    // Elementary
    template <typename R, typename T>
    struct vector_cast_implementation<R, T, false>
    {
        typedef T value_type;
        typedef R result_type;
        static result_type apply(const value_type& value){
            // Simple Conversion
            return value;
        }
    };

    // Vectors
    template <typename R, typename U>
    struct vector_cast_implementation<R, std::vector<U>, true>
    {
        private:
        typedef vector_cast_implementation<R, U> base_cast;

        public:
        typedef std::vector<typename base_cast::value_type> value_type;
        typedef std::vector<typename base_cast::result_type> result_type;
        static result_type apply(const value_type& value){
            result_type result;
            result.reserve(value.size());
            for(const auto& element : value)
                result.push_back(base_cast::apply(element));
            return result;
        }
    };
}

template <typename R, typename T>
typename Detail::vector_cast_implementation<R, std::vector<T>>::result_type
vector_cast(const std::vector<T>& sequence){
    return Detail::vector_cast_implementation<R, std::vector<T>>::apply(sequence);
}

// test
// ====

int main() {
    std::vector<std::vector<std::vector<double>>> v3 = {
        {{ 0.0 , 0.1, 0.2 },
         { 1.0 , 1.1, 1.2 },
         { 2.0 , 2.1, 2.2 }},

        {{ 10.0 , 10.1, 10.2 },
         { 11.0 , 11.1, 11.2 },
         { 12.0 , 12.1, 12.2 }},
    };

    auto r3 = vector_cast<int>(v3);
    for(const std::vector<std::vector<int>>& r2 : r3) {
        for(const std::vector<int>& r1 : r2) {
            for(int e : r1)
                std::cout << e << " ";
        }
        std::cout << "\n";
    }
}

要确定二元 vector 运算的公共(public)类型 R,您可以执行以下操作:

// vector_common_type
// ==================

namespace Detail
{
    template <typename U,typename V, bool = is_vector<U>::value, bool = is_vector<V>::value>
    struct vector_common_type_implementation;

    // Elementary
    template <typename U, typename V>
    struct vector_common_type_implementation<U, V, false, false>
    {
        typedef typename std::common_type<U, V>::type type;
    };

    // Vectors
    template <typename U, typename V>
    struct vector_common_type_implementation<std::vector<U>, std::vector<V>, true, true>
    {
        typedef typename vector_common_type_implementation<U, V>::type type;
    };
}

template <typename U, typename V>
struct vector_common_type;

template <typename U, typename V>
struct vector_common_type<std::vector<U>, std::vector<V>>
: public Detail::vector_common_type_implementation<std::vector<U>, std::vector<V>>
{};

关于c++ - 定义一个 "vector_cast"模板函数,它可以处理可变数量的嵌套 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30896984/

相关文章:

c++ - 如何将 dll 作为服务运行?

c++ - 为什么我的字符串的开头消失了?

c++ - 在指向数组转换的指针的上下文中,有人可以解释为什么这些转换是合法的还是非法的?

swift - 使用Any类型是一个好的解决方案时,有没有具体的例子?

c - 双重类型转换与双重功能

c++ - 从 ifstream 读取到 stringstream 的有效方法

c++ - 是否有任何适用于延迟着色的独立于顺序的透明技术?

c++ - 实现一个动态数组(我可以访问不存在的位置)

c++ - vector 下标超出范围错误 C++

c++ - 标准库中有哪些函数可以通过编程技巧更快地实现?