I am taking advantage of C++17 new feature to deduce the class member type in a templated class. Specifically, I am doing this:
#include <array>
#include <iostream>
template <std::size_t N = 0>
class A
{
public:
using Array = std::array<int, N>;
A(const Array& arr) : myArr{arr} {}
A() = default;
void show() { std::cout << N << std::endl; }
private:
Array myArr;
};
When I construct A
without indicating N
explicitly, compiler matches correctly the constructor and deduces N
correctly!
std::array<int, 3> data{1, 2, 3};
A a1{data};
A a2;
a1.show(); // prints 3
a2.show(); // prints 0
However, this magic is spoiled as soon as I introduce another template parameter in A
, like this:
template <typename T, std::size_t N = 0>
class A
{
... // same content, no use of T
}
When I construct A
passing any T
like this, it does not compile anymore:
A<int> a1{data};
A<int> a2;
Compiler deduces N=0
in all cases and cannot assign the input std::array<int, 3>
to the deduced parameter in constructor std::array<int, 0>
:
error: no matching function for call to ‘A<int>::A(<brace-enclosed initializer list>)’
A<int> a1{data};
note: candidate: ‘A<T, N>::A(const Array&) [with T = int; long unsigned int N = 0; A<T, N>::Array = std::array<int, 0>]’
A(const Array& arr) : myArr{arr} {}
note: no known conversion for argument 1 from ‘std::array<int, 3>’ to ‘const Array&’ {aka ‘const std::array<int, 0>&’}
A(const Array& arr) : myArr{arr} {}
Could anyone explain why this happens and if it has any solution?
Thank you in advance!