Jump to content
  • Advertisement
Sign in to follow this  
leiavoia

Template Inheritance (or "Dude, where's my scope?")

This topic is 4514 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Let's have two template classes: "First" and "Second". Second is publicly derived from First. My problem is that Second can't seem to see protected class members of First. When Second tries to use them in it's own functions, the compiler complains it doesn't have those variables in scope ("error: 'foo' was not declared in this scope"). I can get around this by putting the exact scope on it, such as "First::", or i can also say "this->". But that seems klunky. Why does this not work with templates the way it normally works with normal classes? And is there an easier way to get around it besides explicitly scoping all of First's protected members when i use them?
template <class TYPE>
class First {
	public:
		virtual void Function() {}
	protected: 
		int test_member;
	};


template <class TYPE>
class Second: public First<TYPE> {
	public:
		virtual void Function() {}
	};


// here is second's function. It wants to use First's "test_member" integer:
template <class TYPE>
void Second<TYPE>::Function() {
	cout << test_member;
	}

// compiler sez:
// "error: 'test_member' was not declared in this scope"

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Dependent name lookup

The C++ standard prescribes that all names that are not dependent on template parameters are bound to their present definitions when parsing a template function or class. Only names that are dependent are looked up at the point of instantiation.

Share this post


Link to post
Share on other sites
And to provide a example as to why this is so.....


template<>
class First<int>
{
public:
virtual void Function() {}
protected:
int not_a_test_member;
};



Because the base class of Second<TYPE> is effectively unknown (First<TYPE> could contain just about anything thanks to template specialisation), there's no way for the compiler to know about test_member. If you had the above code with yours and an instantiation of Second<int> there wouldn't be a test_member in the base class.

You can explicitly tell the compiler that First<TYPE> should have a test_member like this:


template <class TYPE>
void Second<TYPE>::Function()
{
cout << First<TYPE>::test_member;
}



Or if you use it a lot you can explicitly make it visible inside Second<TYPE>


template <class TYPE>
class Second: public First<TYPE>
{
public:
virtual void Function() {}
private:
using First<TYPE>::test_member;
};

Share this post


Link to post
Share on other sites
Thanks.

The using directive was what i wanted but i wasn't sure of the syntax or where to put it. It's messy, but it works!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!