我想编写一个C ++函数,该函数可以在具有以下条件的情况下,对类似STL的通用嵌套容器中的“原子”元素总数进行计数:
每个级别可以是任何类型的容器。
等级数没有先验。
我编写了以下递归函数(使用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完成...递归函数我是否为此目的写了一个过大的杀伤力?
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); }); };
// 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中看到