I've a class that must depend for some reasons from an int
template parameter.
For the same reasons, that parameter cannot be part of the parameter list for the class, instead it is part of the parameter list of its constructor (that is, of course, templated).
Here the problems arose.
Maybe I'm missing something, but I can't see an easy way to provide such a parameter to the constructor, because it cannot be deduced nor explicitly specified.
So far, I've found the following alternatives:
put the above mentioned parameter into the parameter list of the class
create a factory method or a factory function which can be invoked as an example as
factory<42>(params)
provide a traits struct to the constructor
I tried to create a (not so) minimal, working example for the last mentioned solution, also in order to explain better the problem.
The class in the example is not a template class for itself, for the key point is the constructor, anyway the real one is a template class.
#include<iostream>
#include<array>
template<int N>
struct traits {
static constexpr int size = N;
};
class C final {
struct B {
virtual ~B() = default;
virtual void foo() = 0;
};
template<int N>
struct D: public B{
void foo() {
using namespace std;
cout << N << endl;
}
std::array<int, N> arr;
};
public:
template<typename T>
explicit C(T) {
b = new D<T::size>{};
}
~C() { delete b; }
void foo() { b->foo(); }
private:
B *b;
};
int main() {
C c{traits<3>{}};
c.foo();
}
To be honest, none of the solutions above mentioned fits well:
moving the parameter into the parameter list of the class breaks completely its design and is not a viable solution
a factory method is something I'd like to avoid, but it could solve the issue
the traits struct seems to be the best solution so far, but somehow I'm not completely satisfied
The question is pretty easy: is there something I missed out there, maybe an easier, more elegant solution, a detail of the language I completely forgot, or are the three approaches mentioned above the ones from which I must choice?
Any suggestion would be appreciated.
template<int N> explicit C(traits<N>);
(Wheretraits
can betemplate<int N> using traits = std::integral_constant<int, N>;
) – Demetriusintegral_constant
. – Champactemplate<int N> constructor(whatever, you, want)
. – Champac