How to restrict a template argument of Wrapper
to be a Wrapper<Any,
MyArray
<AnyT>>
elegantly?
- Don't break content assist (Visual Studio).
- High readability. Not use a hacky approach.
For some reasons, most solution love to hack. - Make it obvious at the very first line by using C++ syntax rule. (not just green comment)
As far as I know, there are many solutions, but every solution doesn't meet the criteria.
Workaround 1 (template specialization, fail 1)
template<class T> class MyArray{};
template<class T,class T2> class Wrapper;
template<class T,class T2> class Wrapper<T,MyArray<T2>>{
using Test=int;
};
class B{};
class C{};
int main() {
Wrapper<C,MyArray<B>> wrapper;
return 0;
}
This code is modified from https://stackoverflow.com/a/43518221 (@max66).
Context clue / syntax highlighting of IDE will be confused.
In my case, it marks some correct types as error e.g. :-
class ShowError : public Wrapper<B,MyArray<C>>{
Test n=0; //<-- unknown "Test" (intellisense)
};
Workaround 2 (some hacky field/typedef, fail 2)
template<class T> class MyArray{
public: using MyArrayT=T;
};
template<class T,class T2> class Wrapper{
public: using myT=typename T2::MyArrayT;
//^ assert at compile time
};
This idea come from a comment in https://stackoverflow.com/a/43518295 (@Jarod42)
The class declaration doesn't mention about MyArray
, it just uses a hacky (less readable) way (MyArrayT
) to enforce that T2
is MyArray
.
Workaround 3 (base class, fail 2)
class MyArrayBase{};
template<class T> class MyArray : public MyArrayBase{ };
template<class T,class T2> class Wrapper{
//check something around MyArrayBase *object = new T2();
// or "is_base_of"
};
The code is modified from Restrict C++ Template Parameter to Subclass and C++ templates that accept only certain types.
It has same disadvantage as workaround 2.
It is not obvious for common user.
Workaround 4 (SNIFAE, fail 1)
By adding std::enable_if
on the template class declaration (Wrapper
), I can get a working hack.
Unfortunately, content assist hate it.
Reference
Here are the other links that I read :-
- http://www.informit.com/articles/article.aspx?p=376878 (template template parameter)
- restrict a template function, to only allow certain types (not related to template type as a parameter)