表示类模板C++空类型

Represents empty type in C++ class template

本文关键字:类型 C++ 表示      更新时间:2023-10-16

考虑下面的编译时"向量"示例。

#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;
}

我对我们现在能做的事情最满意:定义一个向量,然后从中获取第 n 个元素。我发现不令人满意的一件事是:在基本情况下,我必须使用void *作为假人(向量只包含一个元素而没有尾巴......

我试图有这样的专业化:

template <>
struct static_vector<> {
}

表示空向量。但编译器似乎总是拒绝此定义,并出现以下错误:

<source>:16:8: error: too few template arguments for class template 'static_vector'
struct static_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;
}

专用化必须符合基本模板声明。 由于基本模板至少需要一个int,因此不会编译。

您可以通过声明模板以接受任意数量的int参数,然后专门化接受一个或多个参数的每个案例来实现此工作。 然后,基本声明为空大小写:

template <int...>
struct static_vector {
// Instantiated only for the no-argument case
};
template <int n>
struct static_vector<n> {
// One-argument specialization
};
template <int n, int... ns>
struct static_vector<n, ns...> {
// Two-or-more-argument specialization
};