Reputation: 1010
I am working on Tag dispatching implementation in my SW and am facing weird behavior of my code. Let the code tells more:
I have tag system as follows:
struct GEAR_EXPORT GearParams
{
struct ParameterType
{
using IDType = int;
};
struct GEAR_EXPORT NUM_OF_TEETH : public ParameterType
{
/* NUM_OF_TEETH parameter's unit type definition */
using UnitType = si::dimensionless;
/* NUM_OF_TEETH parameter's data type definition */
using DataType = short;
/* NUM_OF_TEETH parameter's DesignRules DB ID */
using ID = std::integral_constant<ParameterType::IDType, 1>;
};
struct GEAR_EXPORT MODULE : public ParameterType
{
/* MODULE parameter's unit type definition */
using UnitType = si::length;
/* MODULE parameter's data type definition */
using DataType = double;
/* MODULE parameter's DesignRules DB ID */
using ID = std::integral_constant<ParameterType::IDType, 2>;
};
/* ... many others similarly defined as above follows */
};
I know the tags should be left empty classes so that compiler can optimize them away but the advantage of having the type definitions inside exceeds the compiler optimization benefit. I hope this is not the cause of my troubles as described below?
Then I have a ParameterContainer class which supplies a set of templated methods like this one:
template<typename PARAM_IDENTIFICATION>
bool isSet( void ) const
{
/* Once the find() reaches the end of the container, the parameter is not in */
if( mStorage.find( PARAM_IDENTIFICATION::ID::value ) == mStorage.end() )
return( false );
else
return( true );
}
It accepts single template parameter PARAM_IDENTIFICATION which acts as the Tag (Tag dispatching by type). The method is used as follows [WORKS]:
if( TestContainer.isSet<GearParams::NUM_OF_TEETH>() == true )
{
/* do something */
}
This is working fine. But once I try to use it in templated method like this [FAILS]:
template<typename PARAM_IDENTIFICATION>
bool check( void ) const
{
return( mParameters.isSet<PARAM_IDENTIFICATION>() );
}
But even the compilation fails bacause of:
error: expected primary-expression before ‘>’ token
return( mParameters.isSet<PARAM_IDENTIFICATION>() );
^
and
error: expected primary-expression before ‘)’ token
return( mParameters.isSet<PARAM_IDENTIFICATION>() );
^
I know the primary expression error is usually cause by type/instance mixup.
What I do not understand is that when I use the isSet()
method with a complete type GearParams::NUM_OF_TEETH
it works but fails when using the same via templated method:
check<GearParams::NUM_OF_TEETH>();
What is the difference? What's wrong with my code? I would expect the same implementation would behave somehow consistently... am I missing something in my code?
Many thanks in advance to anybody willing to help...
Upvotes: 0
Views: 50
Reputation: 93294
Try mParameters.template isSet<PARAM_IDENTIFICATION>()
.
According to the latest standard draft, $14.2.4:
When the name of a member template specialization appears after . or -> in a postfix-expression or after a nested-name-specifier in a qualified-id, and the object expression of the postfix-expression is type-dependent or the nested-name-specifier in the qualified-id refers to a dependent type, but the name is not a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.
Upvotes: 1