获取类似STL的嵌套容器中的元素总数

问题描述 投票:1回答:1

我想编写一个C ++函数,该函数可以在具有以下条件的情况下,对类似STL的通用嵌套容器中的“原子”元素总数进行计数:

  1. 每个级别可以是任何类型的容器。

  2. 等级数没有先验。

我编写了以下递归函数(使用here中的代码):

template <typename T>
size_t get_total_size(const T & var)
{
    if ( is_container<typeof(var)>::value ) {  // From https://stackoverflow.com/a/9407521/2707864
        typename T::const_iterator iter;
        size_t sumsize = 0;
        for ( iter = var.begin() ; iter!= var.end() ; iter++ ) {
            sumsize += get_total_size(*iter);
        }
        return sumsize;
    } else {
        return 1;
    }
};

编译/链接可能有效。问题在于使用它时(否则,编写它就没有任何意义!)不会编译,因为实例化在“原子”级别变为没有迭代器的类型,例如在此代码中

typedef vector<int> vint;
typedef vector<vint> vvint;
vvint vec_heap;
for (int i=0; i < 12; i++) {
    vec_heap.push_back(vint(2, i));
}
cout << get_total_size(vec_heap) << endl;  // Instantiation leads to compilation errors 

这可能吗?

编辑根据一则评论,可以使用c ++ 17完成...递归函数我是否为此目的写了一个过大的杀伤力?

c++ stl nested container-data-type
1个回答
0
投票
对于C ++ 17,您可以使用if constexpr

template <typename T> size_t get_total_size(const T& var) { if constexpr (is_container<T>::value) { return std::accumulate(var.begin(), var.end(), 0u, [](int acc, const auto& e){ return acc + get_total_size(e); }); } else { return 1u; } };

在此之前,您可能会使用重载和SFINAE:

template <typename T, std::enable_if_t<!is_container<T>::value, int> = 0> size_t get_total_size(const T& var) { return 1u; }; template <typename T, std::enable_if_t<is_container<T>::value, int> = 0> size_t get_total_size(const T& var) { return std::accumulate(var.begin(), var.end(), 0u, [](int acc, const auto& e){ return acc + get_total_size(e); }); };


0
投票
如果不能使用C ++ 17,或者只想打开可以与函数一起使用的标准,则可以切换为使用两个重载,然后使用SFINAE确定何时调用每个重载。使用

// this will be called when T is not a container (it is the "atomic" type) template <typename T, typename std::enable_if<!is_container<T>, bool>::type = true> size_t get_total_size(const T & var) { return 1; }; // this will be called for all container types template <typename T, typename std::enable_if<is_container<T>, bool>::type = true> size_t get_total_size(const T & var) { size_t sumsize = 0; for ( auto iter = var.begin() ; iter != var.end() ; ++iter ) { sumsize += get_total_size(*iter); } return sumsize; };

这将从C ++ 11开始运行,您可以在此live example中看到
© www.soinside.com 2019 - 2024. All rights reserved.