"not declared in this scope" error with templates and inheritance [duplicate] - c++

This question already has answers here:
Why do I have to access template base class members through the this pointer?
(3 answers)
accessing protected members of superclass in C++ with templates [duplicate]
(2 answers)
Closed 8 years ago.
Here is code sample which reproduces my problem:
template <typename myType>
class Base {
public:
Base() {}
virtual ~Base() {}
protected:
int myOption;
virtual void set() = 0;
};
template <typename InterfaceType>
class ChildClass : public Base < std::vector<InterfaceType> >
{
public:
ChildClass() {}
virtual ~ChildClass() {}
protected:
virtual void set();
};
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
myOption = 10;
}
My usage in main():
ChildClass<int> myObject;
I get the following error (gcc 4.4.3 on ubuntu):
‘myOption’ was not declared in this scope
If my ChildClass would be without new template parameter this would work fine, i.e.:
class ChildClass : public Base < std::vector<SomeConcreteType> >
Edit
I've managed to solve it, if my set method looks like:
Base<std::vector<InterfaceType> >::myOption = 10;
It works fine. Still though not sure why I need to specify all template parameters.

myOption is not a dependent name, i.e. it doesn't depend on the template arguments explicitly so the compiler tries to look it up early. You must make it a dependent name:
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
this->myOption = 10;
}
Now it depends on the type of this and thus on the template arguments. Therefore the compiler will bind it at the time of instantiation.
This is called Two-phase name lookup.

C++03 14.6.2 Dependent names
In the definition of a class template or a member of a class template,
if a base class of the class template depends on a template-parameter,
the base class scope is not examined during unqualified name
lookup either at the point of definition of the class template or
member or during an instantiation of the class template or member.
The following code should work.
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
Base<std::vector<InterfaceType> >::myOption = 10;
}

Related

Derived class cannot see base class member [duplicate]

This question already has answers here:
Derived template-class access to base-class member-data
(3 answers)
Closed 2 years ago.
What am I doing wrong in this code?
template <typename T>
class CLASS1
{
public:
T member;
};
template <typename T>
class CLASS2 : public CLASS1<T>
{public:
void func()
{
member = 4;
}
};
Visual Studio error:
member identifier not found
G++ error:
‘member’ was not declared in this scope
You need to specify where the name member comes from. In this case, it comes from the inherited class template CLASS1<T>, so you need to say:
void func()
{
CLASS1<T>::member = 4;
}
If you say this->member, then the compiler knows to look for names in the base classes as well. So you could do:
void func()
{
this->member = 4;
}

Why can't I access members without using this [duplicate]

This question already has answers here:
Why do I have to access template base class members through the this pointer?
(3 answers)
Closed 7 years ago.
I have a templated class that I inherit from, and access through the derived class the base class members.
I can't access them without using "this" and I find a descent reason why.
If I understand correctly, when I use a template, a copy of the templated code is being made with a specialization, and only then it compiles. Meaning if I write vector<int> the compiler makes a copy of vector and replaces all the "T" with "int".
If that is the case, I don't see why there should be any difference between templates and non-templated code.
template <typename T>
class b
{
protected:
int myMember;
};
template<typename T>
class e : public b<T>
{
public:
void dosomething()
{
this->myMember = 2; // Everything is perfect
myMember = 2; // Doesn't compile in GCC, can't find the member
}
};
int main()
{
e<int> mye;
mye.dosomething();
}
Because the base class is dependent on template parameters, the base members are not considered during unqualified lookup.
When you use this-> you use class member lookup instead, which will examine the base class members, even if it is a dependent type.

Accessing base member functions in class derived from template class [duplicate]

This question already has answers here:
Why do I have to access template base class members through the this pointer?
(3 answers)
Closed 8 years ago.
I am developing a library at my work and I have designed a complicated inheritance that includes template classes and deriving from them.
My problem is that a base template class has virtual overloaded operator that takes 2 arguments and returns some value. In base class this operator is implemented and most of derived classes does not reimplement this operator.
Some other class uses derived classes for some work and make use of their operator member function. Everything works just fine as long as derived class has no other overloaded operator, even with different number of arguments. If one does then the base class operator is not accessible using it as object() because compiler can not find proper member function (complains about argument count missmatch).
It does not matter wether default template arguments for base class was specified or not. Also order of definitions of derived classes does not change which operator cause the problem (it is always SpecificDerived class).
Below I present simplified problem.
[EDIT] Example was simplified
Base Class definition:
template<class ret_t>
class TemplateBase2
{
public:
virtual ~TemplateBase2()
{
}
virtual ret_t memberFunc(ret_t x)
{
return x * 2;
}
};
User of derived classes definition:
template <class worker, class ret_t>
ret_t gobble(worker w, float f)
{
return w.memberFunc((ret_t)f);
}
Derived class:
class SpecificDerived2: public TemplateBase2<float>
{
public:
float memberFunc()
{
return 3.14;
}
};
Main function:
#include <iostream>
#include "TemplateBase2.h"
using namespace std;
int main()
{
SpecificDerived2 sd2;
cout << "sd2: " << gobble<SpecificDerived2, float>(sd2, 3.14f) << endl;
return 0;
}
Compiler exits with error claiming that there is no matching function for call to 'SpecificDerived2::memberFunc(float)' from gobble function. Problem exists only when either derived or base class has two overloaded functions of the same name, but different arguments.
I am using MinGW32 4.8.1 with c++11 support.
When a class template derives from a base class template, the base members are not visible in the derived class template definition. (This makes sense; until you specialize, there is no class, and so there are no members. Explicit specializations can always change the meaning of any given template class.)
In other words, the base template member names are dependent names and not looked up in the first phase of template definition lookup.
There are three ways to get around this. Let's make it concrete with a quick example:
template <typename T> struct Foo
{
int data;
using type = const T &;
void gobble() const;
template <int N> void befuddle();
};
template <typename T> struct X : Foo<T> { /* ... */ };
Now in the context of the derived class template definition, you can...
Qualify the name:
Foo<T>::data = 10;
typename Foo<T>::type x;
Foo<T>::gobble();
Foo<T>::template befuddle<10>();
Use this:
this->data = 10;
this->gobble();
this->template befuddle<10>();
(This doesn't work for type names names.)
Use a using declaration:
using Foo<T>::data;
using Foo<T>::gobble;
using type = typename Foo<T>::type;
data = 10;
gobble();
(This doesn't work for template names.)
Update: After your edit, the question is entirely different. Templates don't play a role at all here, since the problem doesn't contain templates, only classes. What's happening is the simple fact that member functions in a derived class hide member functions of the same name in base classes, so the presence of SpecificDerived2::memberFunc hides the base member function. The simple solution is to unhide base members of the same name with a using declaration:
class SpecificDerived2 : public TemplateBase2<float>
{
public:
using TemplateBase2<float>::memberFunc;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
float memberFunc()
{
return 3.14;
}
};

how to inherit a class with templates? [duplicate]

This question already has answers here:
Accessing inherited variable from templated parent class [duplicate]
(2 answers)
Why do I have to access template base class members through the this pointer?
(3 answers)
Closed 9 years ago.
Why would the following work just fine:
class a
{
public:
int n;
};
class b : public a
{
public:
b()
{
n = 1;
}
};
int main()
{
}
but this does not work:
template <class T>
class a
{
public:
int n;
};
template <class T>
class b : public a<T>
{
public:
b()
{
n = 1;
}
};
int main()
{
}
and gives the following error:
1.cpp: In constructor ‘b<T>::b()’:
1.cpp:14: error: ‘n’ was not declared in this scope
and how would one inherit a template class while being able to use its base members and keep the type generic?
You need to qualify it with "this" or with a "using" directive (or explicitly with the base class qualification).
In a nutshell: that variable is a nondependent type (non-dependent on the T of the template class), the compiler doesn't look into a dependent type (your a< T >) when looking for declarations for a nondependent type.
this->n, since "this" refers to a dependent class, works. The same with the other methods I listed.
References:
Faq here: http://www.parashift.com/c++-faq-lite/nondependent-name-lookup-members.html
Live example here: http://ideone.com/nsw4XJ

Inheritance of template classes in C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ Inherited template classes don't have access to the base class
I'm experiencing problems with templates and inheritance. Simply, I have a template class which I want another template class to inherit from. I don't understand why members of base class are not visible within deriving class? Though without using templates everything works as expected. For example:
template <typename T>
class Foo
{
public:
T x;
T y;
void doX(){ x = x+1; }
void doY(){y++;}
protected:
T a;
T b;
void doA(){a++;}
};
template <typename T>
class Bar : public Foo<T>
{
public:
void doX(){x++; y++;} // ERROR
void doY(){x++; y++;} // ERROR
void doA(){a++;b++;} // ERROR
};
These variables are dependent names (read The Dreaded Two-Phase Name Lookup for details), so you need to use this as:
void doX(){ this->x++; this->y++; }
Usually this-> is not required as it is implicit. But here it is required. Actually explicit this-> tells the compiler to look up the name in the second phase when the base class is instantiated, as this case uses two-phase name lookup mechanism.
Or you could qualify them with base class as:
template <typename T>
class Bar : public Foo<T>
{
typedef Foo<T> base; //add this friendly typedef!
public:
void doX(){ base::x++; base::y++;}
//...
};
In this case, the fact that the names cannot be looked-up untill base (which is a typedef of Foo<T>) is instantiated, becomes more obvious (to humans eyes) in my opinion.
If the base class depends on a template parameter, then its members aren't directly available in the derived class definition. Until the template is instantiated, the compiler doesn't know what the base class will contain, and so it won't look up any names from there.
You can force it to treat the names as members by qualifying them:
void doX(){this->x++; Foo<T>::y++;} // OK: both forms specify that it's a member
Write this->x, this->y instead of x, y in derived class functions.
Try referring to the variables using the base class scope:
Foo<T>::x
or use this
this->x