In C ++, all type arguments must have a name, regardless of whether you use it or not, so there is no question mark. Just make it an argument to the function template and give it a name, and everything should be fine.
template <typename T> struct templ { template <typename U> void assign( templ<U> & u );
What is the trivial part, the more complex part contains type restrictions, and for this you can use SFINAE:
template <typename T> struct templ { template <typename U, typename _ = std::enable_if< typename std::is_base_of<U,T>::value >::type > void super( templ<U> & u ); // public void super_<? super T>( templ<?> u ) template <typename U, typename _ = std::enable_if< typename std::is_base_of<T,U>::value >::type > void extends( templ<U> & u ); // public void extends_<? extends T>( templ<?> u ) }
This is the use of C ++ 11 for SFINAE, in C ++ 03, it is a bit more confusing (as if this version was simple), since you cannot use SFINAE in the function template argument, so SFINAE must be applied either to the return type , or to additional function arguments. SFINAE is a much more powerful solution, it can be used not only to provide super
and extends
, but also for many other type functions or compile time values. Google is for SFINAE and you will find many uses of SFINAE, many of them will be C ++ 03 style.
A proposal was made for concepts that would greatly simplify the syntax, but no agreement was reached, and in an attempt to push the standard to completion, it was deferred to a later standard.
Now this is really not as common in C ++ as it is in Java, so I recommend that you ask another question with what you want to do, and you will get ideas for projects in more idiomatic C ++.