Sign in to follow this  
nlbs

C++ template member function of base Class

Recommended Posts

I've a Class that uses Template. header
template <typename KeyType, typename ValueType>
class paramsMapCore : public std::map<KeyType, ValueType>{
  public:
    bool exists(const KeyType& key) const;
    //..... Other methods too
}


source.hpp
template <typename KeyType, typename ValueType>
bool paramsMapCore<KeyType, ValueType>::exists(const KeyType& key) const{
  typename paramsMapCore<KeyType, ValueType>::const_iterator it=find(key);
  return (it != end());
}


When I try to compile it Compiler fires error saying.
error: there are no arguments to 'end' that depend on a template parameter,
  so a declaration of 'end' must be available
I am using inherited the end() method of STL map Here so whats wrong and how to fix ?? there are more similar errors.

Share this post


Link to post
Share on other sites
This link may be of help:

http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html

Notably this line:

"In order to make it clear that you want the member of the base class, you need to defer lookup until instantiation time, at which the base class is known. For this, you need to access i in a dependent context, by either using this->i (remember that this is of type Derived<T>*, so is obviously dependent), or using Base<T>::i. Alternatively, Base<T>::i might be brought into scope by a using-declaration. "

It's for GCC, but most likely applies to VC as well.

Let me know ;-)

Share this post


Link to post
Share on other sites
Thanks that helped.
using this->end() and this->begin() Helps

also I need foreward declaration of My own Classes that doesn't take templated arguments.

However in the mean time I was just looking at STL Map's Source code of GCC

although I didn't find the original one I was looking another one which I believe is almost same with GCC's
http://www.aoc.nrao.edu/~tjuerges/ALMA/STL/html/stl__map_8h-source.html

Here I see Typedefs of iterator and const_iterator is public so
If I just use iterator in my class it SHOULD work.
But It doesn't I need to use
typename paramsMapCore<KeyType, ValueType>::iterator
Instead

Share this post


Link to post
Share on other sites
Why are you inheriting from std::map?

There's no reason for "exists" to be a member function.

If you want a function to do just that, then write a function called exists that takes a map as an argument.

Share this post


Link to post
Share on other sites
I want a Class that have all functionality of stl::map and some additional methods too..
so whats the solution If I cant inherit from stl::map ??

again this class is working correctly even when I inherit from stl::map and I dont see any problem while inheriting from stl::map can you explain whaty kinds of problems may appear ??

does the typedefs too required to be virtual for polymorphism ??

Share this post


Link to post
Share on other sites
Quote:
Original post by nlbs
I want a Class that have all functionality of stl::map and some additional methods too..
so whats the solution If I cant inherit from stl::map ??

again this class is working correctly even when I inherit from stl::map and I dont see any problem while inheriting from stl::map can you explain whaty kinds of problems may appear ??

does the typedefs too required to be virtual for polymorphism ??


paramsMapCore<int, int>* foo = new paramsMapCore<int, int>();
std::map<int, int>* bar = foo;
delete bar;

The problem is that STL containers don't have virtual destructors. They weren't designed to act as base classes.

You should instead consider creating free functions which take a std::map as a parameter. You're going to be using nothing but std::map's public interface either way, so you don't really gain anything from inheritance except some syntactic sugar.

Share this post


Link to post
Share on other sites
In my case I dont need anything special at the time of destruction. so if it clls the STL::map's destructor its OK for me.

I'd be glad If I can see some other problemstoo if exists.

and If I dont need something special job on destructor e.g. If I dont need a custom destructor for my subclass isn't it ok to inherit from a Class that doesn't have a virtual destructor ??

One thing I should mention that My subClass doesn't have any member variable.

template <typename KeyType, typename ValueType>
class paramsMapCore : public std::map<KeyType, ValueType>{
public:
paramsMapCore();
~paramsMapCore();
public:
bool exists(const KeyType& key) const;
virtual ValueType get(const KeyType& key) const;
virtual void set(const KeyType& key, const ValueType& val);
bool remove(const KeyType& key);
void removeAll();
typename paramsMapCore<KeyType, ValueType>::iterator search(const KeyType& key);
typename paramsMapCore<KeyType, ValueType>::const_iterator search(const KeyType& key) const;
typename paramsMapCore<KeyType, ValueType>::iterator each();
typename paramsMapCore<KeyType, ValueType>::const_iterator each() const;
};
#include "paramsmapcore.hpp"






So is there any such problem that might cause malfunctioning ??

Share this post


Link to post
Share on other sites
Quote:
Original post by nlbs
In my case I dont need anything special at the time of destruction. so if it clls the STL::map's destructor its OK for me.

I'd be glad If I can see some other problemstoo if exists.

and If I dont need something special job on destructor e.g. If I dont need a custom destructor for my subclass isn't it ok to inherit from a Class that doesn't have a virtual destructor ??

One thing I should mention that My subClass doesn't have any member variable.

*** Source Snippet Removed ***

So is there any such problem that might cause malfunctioning ??


Yes, the problem is that you're screwing up the design of std::map.

None of the member functions you have 'added on' need to exist at all, and none of them need to be member functions. Why aren't you implementing your algorithms as taking 2 iterators?

Why is there a get() and set() that's virtual? That's silly, as std::map already provides an efficient way of doing this, without virtual functions.

exists() is just map.find(key) != map.end(). Not sure why you needed to make a new type of map that's incompatible with std::map to add this functionality.

Note that you can't assign a std::map to your new kind of map. You also can't pass a std::map to a function that takes a paramsMapCore, even though everything a function would want to do to your map they can also do to a std::map.

You can't call any of the other constructors that std::map provides, so you're stripping away lots of functionality that keeps map efficient. Why???

search() is bad. There's already find(). No reason to rename this stuff, it's conventional and standard, and lots of code already works with std::map.

removeAll() is bad for the same reason search() is. There's already clear().

remove() is bad. There is already erase(). Remove and erase have different conventional meanings in the standard library. Don't blur the line because you are used to a different naming convention.

I have no idea what each() could possibly do, and why it would return an iterator.




In short, don't inherit from standard containers. There's nothing you could add that *needs* access to the internals, and inheriting from it doesn't give you access to the internals, anyway.

Share this post


Link to post
Share on other sites
If I make functions that take a stl::map argument and operates on it I'd not get syntactic flexibility.

get() and set() are virtual cause can be used as a base Class. and suppose a subclass is made on the top of paramsMapCore which needs to do some extra jobs in get() set() operation. So I've made get() and set() reimplementable.

Do you disagree exists() is more syntactically flexible as compared with map.find(key) != map.end()

each() provide's perl like foreach() loop that makes map iteration better and easier.

remove() check wheather the thing exists or not before removing.

removeAll() is an alias of clear() just to give a syntactic similarity.

search() is currently same as find() but might be a bit different in future.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this