How can I achieve in the below code that the compiler will return the intended compilation error message from the assertion in mixer (cf option B)?
#include<iostream>
#include<type_traits>
template<typename _T>
struct Base{
using T=_T;
};
template<typename _T>
struct Derived: Base<_T>{};
template<typename _T>
struct Underived{};
template<typename Q, typename P>
struct Tumbler{};
// CODE OPTION A
template<typename TDerived>
using Mixer = Tumbler<TDerived,typename TDerived::T>;
// CODE OPTION B
template<typename TDerived>
struct Mixer: Tumbler<TDerived,typename TDerived::T>{
static_assert(std::is_convertible<TDerived*, Base<typename TDerived::T>*>::value, "TDerived must be derived of Base");
};
int main(){
Mixer< Derived<float>> mixer_intend;
Mixer<Underived<float>> mixer_misuse; // spits error: "T undefined". I want error "is not derived of base"
std::cout << "passed\n";
}
The issue at hand is that a meaningful assertion of inheritance cannot be posed without knowledge on the type T. Solutions along option A are preferred over solutions along option B.
Application Context
A user may call a SolverFactory for a Derived of an Original Problem instead of a Preprocessed Problem. A solution to the above problem would allow me to hint the user that he/she/it forgot to preprocess the problem first and pass it afterwards. Now instead, the user will look into his/her/its problem to fruitlessly find an error therein.