lundi 29 août 2016

Tag dispatching by type invokes expected primary-expression error

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...

Aucun commentaire:

Enregistrer un commentaire