用另一个类模板实例化一个类样板会导致使用不完整类型



假设我们有以下类模板:

template<size_t S>
struct A
{
char str[S];
};
template<typename T>
class B
{
T t;
public:
void init(); // Should initialize the 't' member in some a way.
};

现在,如果我用一些非模板类型专门化init作为B模板的参数,这是可以的。但是,如果不指定其S值,我就不能用A作为B的参数来专门化它。也就是说,我想做这样的事情:

template<>
void B<A<S>>::init()
{
// Initialize the 't.str'. For example:
memset(t.str, 0, S);
}

要提供执行特定于B<A<???>>的部分专门化,实际上需要为类提供这样一个部分专门化:

#include <cstddef>
#include <cstring>
#include <iostream>
template<std::size_t S>
struct A
{
char str[S];
};
template<typename T>
class B
{
T t;
public:
void init(); // Should initialize the 't' member in some a way.
};
template<std::size_t S>
class B<A<S>> {
using T = A<S>;
T t;
public:
void init(); // Should initialize the 't' member in some a way.
};
template<std::size_t S>
void B<A<S>>::init()
{
// Initialize the 't.str'. For example:
std::memset(t.str, 0, S);
std::cout << "Initialized B<A<" << S << ">>n";
}
int main() {
B<A<3>> b;
b.init();
}

请注意,您的代码有两个关键区别:

  1. 类模板template<std::size_t S> class B<A<S>>存在部分特殊化
  2. 该类模板的init成员函数现在可以定义为template<std::size_t> void B<A<S>>::init() { /* ... */ }

如果您的用例中没有其他实例化有效,则可以省略类模板B的基本用例定义,并将其替换为template<typename T> class B;

实时查看

由于结构体A应该负责其成员的构建和销毁,我建议您执行以下操作:

template <size_t S = 5>
struct A {
A() {
memset(str, 0, S);
}
char str[S];
};

然后你可以有:

template<>
void B<A<>>::init()
{}

更新

正如@NathanOliver所指出的,结构A的默认构造函数甚至不需要。以下也适用:

template <size_t S = 5>
struct A {
char str[S]{};
};

并且,由于初始化char数组的责任传递给结构体A,因此您不需要模板专门化。

最新更新