When using a templated struct as an argument to another templated struct, I've run into some conditions in which automatic template deduction fails. How can I write deduction guides for these three conditions?
#include <cstddef>
#include <array>
template <size_t N>
struct A_args {
std::array<int, N> a;
};
template <size_t N>
struct A {
std::array<int,N> a;
A(A_args<N> const& aa): a{aa.a} {};
};
int main() {
A_args a{std::array{1,2,3,4}};
// Able to deduce N
auto b = A(a);
// Able to deduce N
auto c = A(A_args{std::array{1,2,3,4}});
// Unable to deduce N
auto d = A({std::array<int,4>{1,2,3,4}});
}
template <typename T>
struct A_args {
T a {};
};
template <typename T>
struct A {
A(A_args<T> const& aa = {}) : a{aa.a} {};
T a;
};
int main() {
// Unable to deduce T
auto a = A_args{4};
// Unable to deduce T
auto b = A{{.a = 2}};
}
edited, adding:
#include <cstddef>
#include <array>
template <class... T>
constexpr bool always_false = false;
// Able to deduce N
// Test: deduce from method parameter
template<size_t N>
struct A {
std::array<int, N> a;
A(std::array<int, N> const& a): a{a} {};
};
// Able to deduce N
// Test: deduce from method parameter with inheritance
template <size_t N>
struct A1 : A<N> {
A1(std::array<int, N> const& a): A<N>{a} {};
};
// Able to deduce N
// Test: deduce from method parameter with inheritance and an extra type parameter
template <typename T, size_t N>
struct A2 : A<N> {
static_assert(always_false<T>, "virtual");
};
template <size_t N>
struct A2<int, N> : A<N> {
A2(std::array<int, N> const& a): A<N>{a} {};
};
// Unable to deduce N
// Test: deduce from method parameter with implicit type parameter
// Question: Is there a better method to formulate A<0> from this virtual(-ish) class?
template <typename T>
struct A3 : A<0> {
static_assert(always_false<T>, "virtual");
};
template <size_t N>
struct A3<int> : A<N> {
A3(std::array<int, N> const& a): A<N>{a} {};
};
int main() {
std::array a {1,2,3,4};
// Able to deduce N
auto b = A(a);
auto c = A1(a);
auto d = A2<int, 4>(a);
// Unable to deduce N
auto e = A3<int>(a);
auto e = A3(a);
}