I have the following simplified program:
class Base { };
template < typename T >
class X: public T
{
public:
using TOP = T;
};
// with dependent template parm
template < typename T >
class Y: public X< T >
{
// I have to write down the full name of the base class
using X<T>::TOP::operator =;
};
// without depending template parameter
template < typename T >
class Y: public X< Base >
{
// I simply can use the defined type from the base class
using TOP::operator =;
};
int main()
{
Y< Base > y ;
}
The question is now, if there is any way to simplify the full repetition of the base class type. My original code is something like that:
template < typename VAR_TYPE >
class VarObserved: public ConstructAll2<
UsingHelperV_None,
UsingHelper_None,
CONTAINERL< AssignConst >,
CONTAINERL< Print >,
CONTAINERL< DataStore >,
CONTAINERL< Distribute_ >,
CONTAINERL< EndForward >,
CONTAINERSP< DataStoreBase, VAR_TYPE >
>
{
public:
using SELF = ConstructAll2<
UsingHelperV_None,
UsingHelper_None,
CONTAINERL< AssignConst >,
CONTAINERL< Print >,
CONTAINERL< DataStore >,
CONTAINERL< Distribute_ >,
CONTAINERL< EndForward >,
CONTAINERSP< DataStoreBase, VAR_TYPE > // see text 1)
>;
VarObserved( const VAR_TYPE& var ): SELF{{ var }}{}
using SELF::AssignConst::operator=;
};
As you can see, the full repetition of all the template parameters is not very "nice". Any chance to fix that?
If above code has no dependent template parameter ( change the single line 1.) ) from the example above to:
CONTAINERSP< DataStoreBase, int>
the class becomes totaly simple and much more easy to maintain:
...
VarObserved( const VAR_TYPE& var ): ConstructAll2{{ var }}{}
using AssignConst::operator=;
....
As a reference to the underlying problem I found already that question
"not declared in this scope" error with templates and inheritance
but no idea to simplify my code.
To find the name
TOP
declared in the dependent base class, you can writeY::TOP
instead ofX<T>::TOP
, although since this may confuse readers, you should probably put a comment about why you are doing this.The reason why this works is that it's, well, no longer unqualified lookup. Note that you don't need to write the template arguments out here (
Y
is the injected class name, and means the same thing asY<T>
).