grae22 grae22 - 29 days ago 9
C++ Question

Templatized [] or () operator overload - possible without using type as arg?

In the same way as you can do this...

template< typename T >
T GetValue( const int index ) const;

char c = GetValue< char >( 0 );


...is it possible to do this:

template< typename T >
T operator[]( const char* key ) const;

char c = GetValue< char >( "some key" ); // *** This doesn't compile ***


...or this:

template< typename T >
T Foo::operator()( const char* key ) const;

char c = Foo< char >( "some key" ); // *** This doesn't compile ***


The two examples above don't compile due to the < char > and without it I get the "can't deduce type" error (I understand why that is the case).

The closest I can get is specify a 'default value' which gets rid of the "can't deduce type" error, so something like this:

template< typename T >
T operator()( const char* key, const T& defaultValue ) const;

char c = Foo( "some key", 'x' );


But, that isn't really what I want.

EDIT

Essentially, this is what I'm doing:

class Collection
{
...

template< typename T >
T operator[]( const char* key ) const;

template< typename T >
void Add( const char* key, const T& value );

...
}


And this is how I'd like to use it:

Collection col;
col.Add( "some key", 123 );
col.Add( "another key", 'x' );
col.Add( "and another", 1.23 );

char c = col< char >[ "another key" ];

Answer

If I understood you correctly you want to achieve something like this:

struct S {
   template< typename T >
   T operator[]( const char* key ) const {
       return key[0];
   }
   template< typename T >
   T operator()( const char *key) const {
       return key[0];
   }
};

int main() {
   S s;
   char c = s.operator[]<char>("some key");
   c = s.operator()<char>("some key");
   (void)c;
}

[live demo]


If that syntax doesn't fit your application you could try to use tag dispatching:

struct S {
   template< typename T >
   T operator()(const char *key, T) const {
       return key[0];
   }
};

int main() {
   S s;
   char c = s("some key", char{});
   (void)c;
}

[live demo]

This however can be harder to apply to operator[] as it can only take one argument.