0

The code :

    template< typename... TemplateArguments >
    class Tuple
    {}

    template< typename ExposedType, typename... TemplateArguments >
    class Tuple< ExposedType, TemplateArguments... > : public Tuple< TemplateArguments... >
    {
    public:

        template < uint64_t ArgumentNumber >
        typename std::enable_if< ArgumentNumber != 1, typename TypeHolder< ArgumentNumber, Tuple< ExposedType, TemplateArguments... > >::m_type& >::m_type Entry();

        template < uint64_t ArgumentNumber >
        typename std::enable_if< ArgumentNumber == 1, typename TypeHolder< 1, Tuple< ExposedType > >::m_type& >::m_type Entry();

        ExposedType m_data;

    };

    template< uint64_t ArgumentNumber, typename ExposedType >
    class TypeHolder
    {};

    template< typename ExposedType, typename... TemplateArguments >
    class TypeHolder< 1, Tuple< ExposedType, TemplateArguments... > >
    {
    public:

        typedef ExposedType m_type;

    };

    template< uint64_t NumberOfArguments, typename ExposedType, typename... TemplateArguments >
    class TypeHolder< NumberOfArguments, Tuple< ExposedType, TemplateArguments... > >
    {
    public:

        typedef typename TypeHolder< NumberOfArguments - 1, Tuple< TemplateArguments... > >::m_type m_type;

    };

And the implementation of the entry methods :

    template< typename ExposedType, typename... TemplateArguments >
    template < uint64_t ArgumentNumber >
    typename std::enable_if< ArgumentNumber != 1, typename TypeHolder< ArgumentNumber, Tuple< ExposedType, TemplateArguments... > >::m_type& >::m_type Tuple< ExposedType, TemplateArguments... >::Entry() 
    {
        Tuple< TemplateArguments... >& baseTuple = *this;

        return ( baseTuple.EntryL< ArgumentNumber - 1 >() );
    }

    template< typename ExposedType, typename... TemplateArguments >
    template < uint64_t ArgumentNumber >
    typename std::enable_if< ArgumentNumber == 1, typename TypeHolder< 1, Tuple< ExposedType > >::m_type& >::m_type Tuple< ExposedType, TemplateArguments... >::Entry() 
    {
        return ( m_data );
    }

The point is to create a tuple object that has a method that returns a reference to the required element, when the use should be like this :

Tuple< int, int > tuple_1( 8, 10 );

tuple_1.Entry< 1 >() = 14;

When trying to compile this I get the error :

error: expected primary-expression before ‘)’ token

return ( baseTuple.Entry< ArgumentNumber - 1 >() );
                                                ^

Can anyone help with this problem? or to show the right way how to do this?

Thank you!!

Edit:

It works if I add true :

return ( baseTuple.EntryL< ArgumentNumber - 1 >( true ) );

Why??

  • This has been asked an answered before. But I cannot find the post... The solution was to make some extra templated classes. – JHBonarius Jun 29 '18 at 07:59
  • I'm trying to compile your code using various compilers, but it is incomplete. Could you give a [mcve]? – JHBonarius Jun 29 '18 at 08:08
  • Replace the CreateTypedef with std::enable_if and it will do the trick, my bad – rrrrTTTrrrr Jun 29 '18 at 08:10
  • No, it didn't [good link now](https://wandbox.org/permlink/KZU3Q7JMBfIj12Rg) – JHBonarius Jun 29 '18 at 08:19
  • You're welcome, although I did nothing. Still figuring out how get your code to compile. Had to add `Tuple(ExposedType data, TemplateArguments... args) : Tuple(&args...), m_data(data) {}` for instance. And put the definition of `Typeholder` above the specialization of `Tuple`. P.s. PM people using @, not #. – JHBonarius Jun 29 '18 at 08:52
  • ok, it had to be `Tuple(ExposedType data, TemplateArguments... args) : Tuple< TemplateArguments... >(args...), m_data(data) {}` – JHBonarius Jun 29 '18 at 09:56
  • And I did `template < UnsignedInteger64bits ArgumentNumber, typename std::enable_if_t< ArgumentNumber == 1, int > = 0> ExposedType& Entry() { return m_data; }` for instance – JHBonarius Jun 29 '18 at 09:57
  • Did you consider using C++17 `decltype(auto)`? Removes the necessity of `TypeHolder`. Example: [live](https://wandbox.org/permlink/PiimiWMe2gOTk9we) – JHBonarius Jun 29 '18 at 11:01

1 Answers1

1

Dependent name, you should add template:

return baseTuple.template Entry<ArgumentNumber - 1>();
Jarod42
  • 203,559
  • 14
  • 181
  • 302