I would like to write this code, but it produces an error.
template<int N>
struct A {
struct B {
};
B f() { return B{}; }
};
template<typename T>
constexpr bool val = false;
template<int N>
constexpr bool val<typename A<N>::B> = true;
error: template parameters not deducible in partial specialization:
13 | constexpr bool val<typename A<N>::B> = true;
While this code is working perfectly
template<int N> struct A;
template<int N>
struct AB {
};
template<int N>
struct A {
AB<N> f() { return AB<N>{}; }
};
template<typename T>
constexpr bool val = false;
template<int N>
constexpr bool val<AB<N>> = true;
I understood that C++ would have to check if there exists a N
such that T
equals A<N>::B
when evaluating val<T>
which is too difficult. That's why there is an error. But my question is: Is there any way of keeping the struct B inside A and defining the value val<A<N>::B>
for every N
?
I understand the error if B was defined as a reference to a struct outside A (for instance using B = int;
) but if B is a struct defined inside A then there is no ambiguity and N
is easily deduced.
If you provide way to retrieve template parameters of A
from B
, you might do it by SFINAE/constraint:
template<int N>
struct A {
struct B {
constexpr static int value = N;
};
};
template <typename T>
constexpr bool val = false;
template <typename T>
requires (std::is_same_v<typename A<T::value>::B, T>) // C++20
constexpr bool val<T> = true;