I want to enable user to control "internal type" of base class. This code works fine.
Version 1 (demo)
//library layer
template<class Derived> class BT_trait{
public: using type=int;
};
template<class Derived> class BT{
public: using typee=typename BT_trait<Derived>::type;
public: typee f(){ return 1;}
};
//user code below
class C;
template<> class BT_trait<C>{
public: using type=std::string; //<-- user want to set "internal type"
};
class C : public BT<C> {
public: typee f(){ return "OK";}
};
int main(){
C bt;
std::cout<< bt.f();
}
If I make it a little more complex by adding a template parameter, it will not compilable anymore.
(show below)
Version 2 (demo)
template<class Derived> class BT_trait{
public: using type=int;
};
template<class Derived,class Dummy> class BT{
public: using typee=typename BT_trait<Derived>::type;
public: typee f(){ return 1;}
};
//user code below
template<class T> class C;
template<class T> class BT_trait<C<T>>{
public: using type=std::string;
};
template<class T> class C : public BT<C<T>,T> {
// public: typename BT<C<T>, T>::typee f(){ return "OK";} //Version #2b
public: typee f(){ return "OK";} //Version #2a
//^ error: 'typee' does not name a type; did you mean 'wctype'?
};
int main(){
C<int> bt;
std::cout<< bt.f();
}
But if I use #2b
(dirty) instead of #2a
(concise), the above code will work fine.
Why? Is it possible to make #2a
work?
According to a quote from Specialization of template function after point of use will break the compilation :-
Section [temp.expl.spec] 14.7.3p6 : If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.
I doubt that my code is undefined behavior. Correct?
I am very new to template specialization.