Lets say I have this class:
template <class T>
class Test
{
Test(T* x);
const T* const t;
int i{0};
};
I want t
to always be initialized with x
:
template <class T> Test<T>::Test(T* x) : t{x} {}
And I have two specializations:
template <> Test<Foo>::Test(Foo* x) : t{x} { i = 1; }
template <> Test<Bar>::Test(Bar* x) : t{x} { i = 2; }
Next, I'm extending the class with some other stuff, and that first (templated) constructor does a lot more than just setting t
.
All things that I want to do for both T = Foo
and T = Bar
.
Is there some way that I can call the templated constructor from the specialized constructors?
//This does not work, since it will create a delegation cycle
template <> Test<Foo>::Test(Foo* x) : Test(x) { i = 1; }
template <> Test<Bar>::Test(Bar* x) : Test(x) { i = 2; }
You can use a delegating constructor for this.
You can create a private constructor, that takes the pointer for t
, and an int
for i
. Then you can use that to set x
and i
, and run all of the shared code.
That would look like:
template <class T>
class Test
{
public:
Test(T* x) : Test(x, 0) { /*code for default case, runs after delegate*/ }
private:
Test(T* t, int i) : t(t), i(i) { /*code to run for everything*/ }
const T* const t;
int i;
};
template <> Test<Foo>::Test(Foo* x) : Test(x, 1) { /*code only for Foo, runs after delegate*/ }
template <> Test<Foo>::Test(Bar* x) : Test(x, 2) { /*code only for Bar, runs after delegate*/ }
Can the delegate constructor be the generic/templated constructor (with the same signature as the specific, specialized constructors for Foo and Bar)?
No, that isn't possible. When you specialize a function template, you aren't creating a new function, but instead specifying that if T
gets deduced to the type you specify in the specialization, then use the specialization definition in place of the generic one.
That is why I have "all three constructors" (the generic and the two specializations) call Test(T* t, int i)
, which handles the code that is shared by all cases.
have you thought about inheritance? The first thing that comes to my mind is making a Test
class derived from the base class that will have all the things that you wanted the same for both foo and bar took care of. So you could call the base class constructor inside derived class (Test), and then just do things for Foo
and bar
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With