Reputation: 1807
Let's say, we have the following class templates:
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.
};
Now, if I specialize the init
with some non-template types as parameter of the B
template, it's OK. But, I can not specialize it with the A
as the parameter of the B
without specifying its S
value. I.e., I'd like to do something like this:
template<>
void B<A<S>>::init()
{
// Initialize the 't.str'. For example:
memset(t.str, 0, S);
}
Upvotes: 0
Views: 38
Reputation: 12253
Since struct A
should be responsible for construction and destruction of its members, I suggest you doing the following:
template <size_t S = 5>
struct A {
A() {
memset(str, 0, S);
}
char str[S];
};
and then you can have:
template<>
void B<A<>>::init()
{}
UPDATE
As @NathanOliver pointed out, default constructor for struct A
is not even needed. Following would work too:
template <size_t S = 5>
struct A {
char str[S]{};
};
and, since responsibility of initializing the char
array is passed to struct A
, you do not need template specialization.
Upvotes: 0
Reputation: 11116
To provide a partial specialization, that performs something specific to B<A<???>>
, you need to actually provide such a partial specialization for the class:
#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();
}
Note that there are two key differences to your code:
template<std::size_t S> class B<A<S>>
init
member function of that class template can now be defined as template<std::size_t> void B<A<S>>::init() { /* ... */ }
You can omit the base case definition of the class template B
and replace it with template<typename T> class B;
if no other instantiation is valid in your use case.
Upvotes: 2