I have overloaded the subscript operator in a custom class as below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
template<class T, class I = int>
class Indexed_Object
{
public:
template<class R>
R& operator[](const I& indexer) {
returnthis->m_value.operator[](indexer);
}
template<class R>
const R operator[](const I& indexer) {
returnthis->m_value.operator[](indexer);
}
private:
T m_value;
};
I am using the class like this (I am just testing at the moment):
1 2 3 4 5 6 7 8 9 10
// this works perfectly...
Indexed_Object<int*> d;
d = newint[2];
d[0] = 100;
d[1] = 101;
// this throws an error saying that operator[] does not exist in a['a']...?
// essentially calls std::map<char,int>.operator[]('a') = 1;
Indexed_Object< std::map<char, int> > a;
a['a'] = 1;
If the operator[] has not been defined in type T then I would expect it to throw an error but I know that it has been defined in this case. Does anyone know what is going on? It happens on all types STL and my own classes when I use anything other than an integer as the index?
I would like to thank you in advance for any help that is offered.
Thank you for the reply. I had missed that off the original post as at the time I was playing with various ways of trying to get it to work so thanks for pointing that out. I have edited it to be correct now. However, with the below:
The exact error I get is "Error: no match for operator[] in 'a['a']'". This is on gcc 4.0 if that helps but i'm pretty sure that it's something i've done wrong in the implementation - i'm just not sure what. :-)
error C2783: 'const R Indexed_Object<T,I>::operator [](const I &)' : could not deduce template argument for 'R'
error C2783: 'R &Indexed_Object<T,I>::operator [](const I &)' : could not deduce template argument for 'R'
error C2676: binary '[' : 'Indexed_Object<T,I>' does not define this operator or a conversion to a type acceptable to the predefined operator
This seems to say that it is ambiguous, and it indeed is. The compiler has to know what the template parameter R has to be, and it can't use the returned type for that. That is illegal, and for good reason:
What is the template value for R? Will it ever compile if you specify is as int or char*, or std::string? No, this is illegal, and it is forbidden altogether.
In your case, I think you can specify the template parameter R as int when you call operator[].
Thanks for the quick reply - that makes a lot more sense than the error I was getting. Also, good explanation as well. Much appreciated.
The problem I have is as you said, the compiler, and myself as well, do not know what type will be returned. For instance the Indexed_Object could contain a map<char, int> or a custom class that holds a collection pointers or even more classes. That is originally why I specified a template parameter. I need it to be as generic as possible.
What would be the best way of doing this - or am I doomed from the start? :-)
The problem I have is as you said, the compiler, and myself as well, do not know what type will be returned.
that's not the way C++ templates work - the compiler must be able to determine the type at compile time or your code won't build
if you like, you can use a more generic type as your second parameter like boost::any - however, that would defeat half the purpose of using templates in the first place - when you retrieve the values, you will have to turn boost::any back to a specific type
Hi - thanks for the reply. I was kinda hoping for a solution that didn't use any classes other than those supplied by the STL. Thank you both for your help though it is greatly appreciated.