I'm trying to figure out how to make the compiler deduce template parameters based on arguments passed to the constructor. Here's what I tried:
#include <array>
template<size_t N, size_t M>
class A {
public:
A(const std::array<float, N>& n, const std::array<double, M>& m)
: nElements(n), mElements(m) {
}
private:
std::array<float, N> nElements;
std::array<double, M> mElements;
};
int main() {
A<2, 3> a({1.4f, 2.5f}, {3.0, 2.1, 4.8});
// ^
// |
// how can i avoid <2,3> expclicit declaration here?
}
Thank you very much for any possible help!
As @Thomas's answer says, you can't deduce the class template arguments from the constructor arguments till c++17.
But providing a deduction guide won't work in this case, as pointed out in the comments, since the template arguments of std::array can't be deduced from a brace-init-list.
We can sidestep this issue by creating a deduction guide where the arguments are raw arrays. This solves the problem since the size of raw arrays can be deduced from brace-init-lists.
// deduce the size using raw arrays
template<size_t N, size_t M>
A(float const (&)[N], double const (&)[M]) -> A<N,M>;
int main() {
A a({1.4f, 2.5f}, {3.0, 2.1, 4.8}); // yay
}
C++ doesn't deduct the arguments of the class template from arguments passed to the class's constructor, until C++17.
In versions before C++17, the customary workaround is to create a factory function:
template<size_t N, size_t M>
A<N, M> make_A(const std::array<float, N>& n, const std::array<double, M>& m) {
return A<N, M>(n, m);
}
You see examples of these in the standard library as well, such as std::make_pair
and std::make_shared
.
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