假设我想要一个class/struct
类型,继承自integral_constant<size_t, N>
,其中N是维度,维度的实现如下:
template<class T>
struct dimension;
template<class T>
struct dimension<vector<T>> : integral_constant<size_t, 1> {};
template<class T>
struct dimension<vector<vector<T>>> : integral_constant<size_t, 2> {};
然后
cout << dimension<vector<int>>::value; // 1
cout << dimension<vector<vector<int>>>::value; // 2
但显然这并不完美,因为维度的数量可以是无限的(理论上)。有没有办法实现这个通用的解决方案?
建议:我朝着这个方向前进,但没有进一步:
template<class T, class... Tn>
struct dimension<vector<Tn...>> : integral_constant<size_t, sizeof...(Tn)> {};
由于std::vector
有其他模板参数,因此无效。
答案 0 :(得分:3)
有点难以定义&#34;什么是容器&#34;。以下检查value_type
,iterator
和const_iterator
嵌套typedef。根据需要调整void_t
检查。 (例如,如果您只想将可以下标的内容识别为容器,则将decltype(std::declval<T&>()[0])
添加到列表中。)
请注意dimension_impl
的专精调用dimension
。这样,您就可以将dimension
专门用于容器般的事情,而不想将其视为容器(std::string
会浮现在脑海中)。
template<class T> struct dimension;
namespace details {
template<class T, class = void>
struct dimension_impl {
static constexpr std::size_t value = 0;
};
template<class T>
struct dimension_impl<T, std::void_t<typename T::value_type,
typename T::iterator,
typename T::const_iterator>> {
static constexpr std::size_t value = 1 + dimension<typename T::value_type>::value;
};
}
template<class T>
struct dimension : std::integral_constant<std::size_t,
details::dimension_impl<T>::value> {};
答案 1 :(得分:2)
您可以为std::vector
执行此操作(请注意std::vector
的模板参数列表长于1):
template<typename T>
struct dimension { static constexpr std::size_t value = 0; };
template<typename T, typename... V>
struct dimension<std::vector<T, V...>>{
static constexpr std::size_t value = 1 + dimension<T>::value;
};
这适用于std::array
:
template<typename>
struct dimension { static constexpr std::size_t value = 0; };
template<typename T, std::size_t N>
struct dimension<std::array<T, N>>{
static constexpr std::size_t value = 1 + dimension<T>::value;
};
它遵循一个最小的工作示例:
#include<vector>
#include<iostream>
template<typename T>
struct dimension { static constexpr std::size_t value = 0; };
template<typename T, typename... V>
struct dimension<std::vector<T, V...>>{
static constexpr std::size_t value = 1 + dimension<T>::value;
};
int main() {
std::cout << dimension<std::vector<std::vector<int>>>::value << std::endl;
}