Template partial specialisation/inheritance problem

J

Jules

I have the following code which isn't working as I expect it to:

---
#include <iostream>
using namespace std;

class mystring
{
public:
mystring (const char * src) { /* ... */ }
};

template<class K, class V>
class Map
{
public:
// ...
virtual V& operator[] (K& value) = 0;
};

template<class V>
class Map<mystring, V>
{
public:
// ...
virtual V& operator[] (mystring& value) = 0;

// plus additional operator:
V& operator[] (const char * v) {
mystring str(v);
return (*this)[str];
}
};

template<class K, class V>
class Hashtable : public Map<K, V>
{
V test;
public:
virtual V& operator[] (K& value) { return test; }
};

int main (void)
{
Hashtable<mystring, int> test;
cout << test["hello"] << endl;
}
---

When I attempt to compile this, I get the following error message from
g++ (3.3):

tps.cpp: In function `int main()':
tps.cpp:43: error: no match for 'operator[]' in 'test["hello"]'
tps.cpp:37: error: candidates are: V& Hashtable<K, V>::eek:perator[](K&)
[with K = mystring, V = int]

This isn't what I expect to happen because Hashtable<mystring,int> is
derived from Map<mystring,int> which should (surely?) be expanded based
on the partially specialized template which includes an
'operator[](const char *)' that should match this call. Everything
works fine if I take out the inheritance and specialize Hashtable
directly, but I want to be generic in implementation and have an
abstract base class with all the methods declared...

Anyone know why this doesn't work?

(please only reply to the group; I can't currently read e-mail sent to
the address quoted above)
 
V

Victor Bazarov

Jules said:
I have the following code which isn't working as I expect it to:

---
#include <iostream>
using namespace std;

class mystring
{
public:
mystring (const char * src) { /* ... */ }
};

template<class K, class V>
class Map
{
public:
// ...
virtual V& operator[] (K& value) = 0;

You might consider making it

virtual V& operator[] (K const& value) = 0;
};

template<class V>
class Map<mystring, V>
{
public:
// ...
virtual V& operator[] (mystring& value) = 0;

Here as well...
// plus additional operator:
V& operator[] (const char * v) {
mystring str(v);
return (*this)[str];
}
};

template<class K, class V>
class Hashtable : public Map<K, V>
{
V test;
public:
virtual V& operator[] (K& value) { return test; }
};

int main (void)
{
Hashtable<mystring, int> test;
cout << test["hello"] << endl;
}
---

When I attempt to compile this, I get the following error message from
g++ (3.3):
[...]

V
 
A

Alipha

Jules said:
I have the following code which isn't working as I expect it to:

---
#include <iostream>
using namespace std;

class mystring
{
public:
mystring (const char * src) { /* ... */ }
};

template<class K, class V>
class Map
{
public:
// ...
virtual V& operator[] (K& value) = 0;
};

template<class V>
class Map<mystring, V>
{
public:
// ...
virtual V& operator[] (mystring& value) = 0;

// plus additional operator:
V& operator[] (const char * v) {
mystring str(v);
return (*this)[str];
}
};

template<class K, class V>
class Hashtable : public Map<K, V>
{
V test;
public:
virtual V& operator[] (K& value) { return test; }
};

int main (void)
{
Hashtable<mystring, int> test;
cout << test["hello"] << endl;
}
---

When I attempt to compile this, I get the following error message from
g++ (3.3):

tps.cpp: In function `int main()':
tps.cpp:43: error: no match for 'operator[]' in 'test["hello"]'
tps.cpp:37: error: candidates are: V& Hashtable<K, V>::eek:perator[](K&)
[with K = mystring, V = int]

This isn't what I expect to happen because Hashtable<mystring,int> is
derived from Map<mystring,int> which should (surely?) be expanded based
on the partially specialized template which includes an
'operator[](const char *)' that should match this call. Everything
works fine if I take out the inheritance and specialize Hashtable
directly, but I want to be generic in implementation and have an
abstract base class with all the methods declared...

Anyone know why this doesn't work?

(please only reply to the group; I can't currently read e-mail sent to
the address quoted above)

the function in the base is hidden. see the FAQ.
 
J

Jules

the function in the base is hidden. see the FAQ.

Err, OK. Don't know how I missed that before. :(

I think I understand now... but I'm having trouble trying to figure out
a workaround. How do I change it so that this works without explicitly
specializing Hashtable (and potentially BTreeMap, and
ReferenceToJavaMap, and ReferenceToPythonDictionary, etc...)?
 
V

Victor Bazarov

Jules said:
Err, OK. Don't know how I missed that before. :(

I think I understand now... but I'm having trouble trying to figure out
a workaround. How do I change it so that this works without explicitly
specializing Hashtable (and potentially BTreeMap, and
ReferenceToJavaMap, and ReferenceToPythonDictionary, etc...)?

Add

using Map<K,V>::eek:perator[];

to the public section of Hashtable template.

V
 
A

Alipha

Jules said:
I have the following code which isn't working as I expect it to:

---
#include <iostream>
using namespace std;

class mystring
{
public:
mystring (const char * src) { /* ... */ }
};

template<class K, class V>
class Map
{
public:
// ...
virtual V& operator[] (K& value) = 0;
};

template<class V>
class Map<mystring, V>
{
public:
// ...
virtual V& operator[] (mystring& value) = 0;

// plus additional operator:
V& operator[] (const char * v) {
mystring str(v);
return (*this)[str];
}
};

template<class K, class V>
class Hashtable : public Map<K, V>
{
V test;
public:

using Map said:
virtual V& operator[] (K& value) { return test; }
};

int main (void)
{
Hashtable<mystring, int> test;
cout << test["hello"] << endl;
}
---

When I attempt to compile this, I get the following error message from
g++ (3.3):

tps.cpp: In function `int main()':
tps.cpp:43: error: no match for 'operator[]' in 'test["hello"]'
tps.cpp:37: error: candidates are: V& Hashtable<K, V>::eek:perator[](K&)
[with K = mystring, V = int]

This isn't what I expect to happen because Hashtable<mystring,int> is
derived from Map<mystring,int> which should (surely?) be expanded based
on the partially specialized template which includes an
'operator[](const char *)' that should match this call. Everything
works fine if I take out the inheritance and specialize Hashtable
directly, but I want to be generic in implementation and have an
abstract base class with all the methods declared...

Anyone know why this doesn't work?

(please only reply to the group; I can't currently read e-mail sent to
the address quoted above)
Alipha wrote:
the function in the base is hidden. see the FAQ.

Err, OK. Don't know how I missed that before. :(

I think I understand now... but I'm having trouble trying to figure out
a workaround. How do I change it so that this works without explicitly
specializing Hashtable (and potentially BTreeMap, and
ReferenceToJavaMap, and ReferenceToPythonDictionary, etc...)?

see above addition to your code.
 
J

Jules

Add
using Map<K,V>::eek:perator[];

to the public section of Hashtable template.

Thank you! Didn't realise I could refer to it like that without
specifying the type of parameter. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top