考虑以下编译时“vector ”的示例。
#include <iostream>
template <int n, int...ns>
struct static_vector {
static constexpr int value = n;
static_vector<ns...> rest;
};
template <int n>
struct static_vector<n> {
static constexpr int value = n;
void* rest;
};
template <int n, class sv>
constexpr int access_nth() {
static_assert(n >= 0, "vector size out of bound");
if constexpr(n == 0) {
return sv::value;
} else {
static_assert(!std::is_same_v<decltype(sv::rest), void *>, "vector size out of bound");
return access_nth<n-1, decltype(sv::rest)>();
}
}
int main()
{
constexpr auto a = static_vector<12, 23, 34, 45>();
constexpr int nth = access_nth<5, decltype(a)>();
std::cout << nth << std::endl;
}
我对我们现在能做的事情非常满意:定义一个 vector ,然后从中获取第 n 个元素。我发现不满意的一件事是:我必须在基本情况下使用 void *
作为虚拟对象(其中 vector 仅包含一个元素而没有尾部...)
我尝试过这样的特化:
template <>
struct static_vector<> {
}
代表空 vector 。但编译器似乎总是拒绝这个定义并出现以下错误:
<source>:16:8: error: too few template arguments for class template 'static_vector'
struct static_vector<> {
^
我应该在这里做什么才能得到一个空 vector ?
非常感谢。
最佳答案
但是为什么要递归呢?
您标记了 C++17,以便可以使用模板折叠,那么...下面怎么样?
#include <iostream>
template <int ... Is>
struct static_vector
{
template <std::size_t N>
int get () const
{
static_assert( N < sizeof...(Is), "index out of bound" );
std::size_t i{};
int ret;
( ... , (N == i++ ? ret = Is : 0) );
return ret;
}
};
int main()
{
constexpr auto a = static_vector<12, 23, 34, 45>();
std::cout << a.get<3u>() << std::endl;
}
关于c++ - 代表C++类模板中的空类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62721992/