C++ using-declarations - c++

What is the point of the following using-declarations
using eoPop<MOEOT>::size;
using eoPop<MOEOT>::operator[];
using eoPop<MOEOT>::back;
using eoPop<MOEOT>::pop_back;
Taken from the class defined here. Surely, because eoPop<EOT> inherits std::vector<EOT>, the methods size, operator[] , back and pop_back are public there is no need for the using declaration. Are the using declaration used to force instantiation?

Although I don't know why they've decided to include those using-declarations, I can tell why the code would be ill-formed without them.
But first, repeating from a comment:
A using-declaration doesn't require the existence of the definition the nominated entity (here: it doesn't require the existence of the definition of those functions). Consider:
void foo();
int main()
{
using ::foo; // doesn't require the definition of `foo` to exist
return 0;
}
If a class template gets implicitly instantiated, the declarations of its member functions are instantiated, but not their definitions (as per [temp.inst]/1). The base classes of a class template are also instantiated if said class template is implicitly instantiated (which in turn leads to the instantiation of the declarations of the member functions of those base class templates). Therefore, the using-declaration doesn't help with instantiation.
An effect of those using-declarations is that the names declared are visible for non-dependent name lookup. As per [temp.dep]/3
In the definition of a class or class template, if a base class depends on a template-parameter, the base class scope is not examined during unqualified name lookup [...].
In the linked code, we find for example i<size(). The name size here is non-dependent, therefore the base class scope is not searched, and eoPop < MOEOT > :: size would not be found without the using-declaration.
Another reason to use using-declarations is if you want to overload a member function of a base class. If you don't use the using-decl, the member function in the derived class simply hides every overload (with the same name) in the base class. As far as I can see, this is not used in the linked code.

Related

why template base class is not forced to be instantiated [duplicate]

I figured an explicit instantiation request would automatically instantiate all base class members also, but I get a linker error: unresolved external symbol "public: void Base<int>::foo(int)" when building this code using Visual Studio 2008 or 2010.
Note that adding a call to foo() inside bar() forces the compiler to instantiate Base<int>::bar() and the build succeeds, so it appears that the compiler has all the necessary information to instantiate foo().
Obviously, explicitly instantiating Base<int> in source.cpp allows the build to succeed, but it seems silly to need to explicitly instantiate any dependent base classes whenever explicitly instantiating a derived class.
Is this normal? I couldn't find what the standard says regarding this issue.
header.h
template<typename T>
class Base {
public:
void foo();
};
template<typename T>
class Derived : public Base<T> {
public:
void bar();
};
source.cpp
#include "header.h"
template<typename T>
void Base<T>::foo() { }
template<typename T>
void Derived<T>::bar() {
// this->foo(); // adding this forces instantiation of foo()???
}
template class Derived<int>;
main.cpp
#include "header.h"
int main() {
Derived<int> d;
d.foo(); // Linker Error: unresolved external symbol "public: void Base<int>::foo(int)"
}
Edit:
It looks like the Standard says only members of a class get instantiated by an explicit class instantiation, so the linker error is justified in my example.
Note that a class is defined by class-head { member-specification } and "The member-specification in a class definition declares the full set of members of the class; no member can be added elsewhere." So members are only between the curly braces { }, and public base class members don't become members of the derived class, they are merely accessible from the derived class or by objects of the derived class.
My only remaining question is why the Standard specifies that explicit instantiation of a class template only instantiates members and not members of base classes? My guess is that this allows greater control of what gets explicitly instantiated where. Someone that's using explicit template class instantiations would most likely have the base class definitions in a different file than the derived class definitions, and would explicitly instantiate each separately.
The Standard says
The explicit instantiation of a class template specialization implies the instantiation of all of its members not previously explicitly specialized in the translation unit containing the explicit instantiation.
In other words, it does not mandate that base classes are explicitly instantiated in turn. It will cause an implicit instantiation of them which will not instantiate their member definitions up-front. It's some ugly glitch in the Standard as to whether some text when it says "member" means "direct" or "inherited" member, as that often seems to be "obvious" to the one who wrote the Standards wording, but not to the one who reads it. C++0x has added some clarifications (it also has a difference between explicit instantiation declarations and definitions that C++03 doesn't have, but even ignoring that, the C++0x wording contains some more bits of insight):
An explicit instantiation that names a class template specialization is also an explicit instantiation of the
same kind (declaration or definition) of each of its members (not including members inherited from base
classes) that has not been previously explicitly specialized in the translation unit containing the explicit
instantiation, except as described below. [ Note: In addition, it will typically be an explicit instantiation of
certain implementation-dependent data about the class. — end note ]

class member function definition after forward declaration of class, before class declaration

i got below compilation problem, while defining member function. is there a way to define member function before class declaration but with forward declaration?
error: invalid use of incomplete type ‘class GetErrorLogInterfaceTest’
class GetErrorLogInterfaceTest; // forward declaration of class
void GetErrorLogInterfaceTest::initializeJsonFile() { // member function definition
}
class GetErrorLogInterfaceTest : public ::testing::Test {
public:
void initializeJsonFile(); // member function declaration
}
No. It is not possible to define member functions of incomplete classes. It is only possible to define member functions of those classes that have been defined. A forward declaration is not sufficient.
The standard says in [class.mfct]:
A member function may be defined (11.4) in its class definition, in which case it is an inline member
function (10.1.6), or it may be defined outside of its class definition if it has already been declared but not
defined in its class definition. ...
Now, the rule does not say that member functions may only be defined in these two places, so unless you know that standard has no other rule which allows a member function definition somewhere else (which it doesn't, as far as I know), then this by itself isn't technically complete information.
However, the paragraph continues
... Except for member function definitions
that appear outside of a class definition, and except for explicit specializations of member functions of class
templates and member function templates (17.8) appearing outside of the class definition, a member function
shall not be redeclared.
Note that a member function shall not be redeclared within the class definition. If the member function were defined before the class definition, then the function declaration within the class definition would be a redeclaration, and would violate this rule.
No. The standard covers this trivial aspect as well.
From CPP draft (N4713)
12.2.1 Member functions [class.mfct]
A member function may be defined in its class definition, in which case it is an inline member function, or it may be defined outside of its class definition if it has already been declared but not defined in its class definition.
So the class definition is first necessary to define the member function in either one of the ways mentioned above.

C++: Does inheriting from a class bring it into the namespace?

Here's some contrived example code:
template<typename T> void Do(T arg) { (void)arg->b; }
namespace A {
struct Foo { int a; };
}
namespace B {
struct Foo { int b; };
struct Bar : A::Foo {
void Blah() { Do((Foo *)0); }
};
}
Which when compiled with gcc 4.8.2 (clang gives a similar error):
namespacebug.cpp: In instantiation of ‘void Do(T) [with T = A::Foo*]’:
namespacebug.cpp:10:34: required from here
namespacebug.cpp:1:39: error: ‘struct A::Foo’ has no member named ‘b’
template<typename T> void Do(T arg) { (void)arg->b; }
^
Note in the error it refers to T = A::Foo even though at the call-site I am creating a Foo within namespace B. If I remove the base class decl (: A::Foo) then all compiles fine.
This appears to suggest that inheriting from A::Foo somehow brings it into my namespace and matches it to my use of Foo? What C++ "feature" causes this?
(Of course, this issue can easily be fixed by namespacing my use of Foo, but that's not the question.)
Because of the injected-class-name rule, the name of a class is visible as though it were a member.
9/2
A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name.
So it is as though class A::Foo contains a member Foo which names the type A::Foo. Since name lookup in Bar::Blah() considers base members of Bar before namespace members, the name lookup for Foo finds the injected-class-name, which names A::Foo.
Does inheriting from a class bring it into the namespace?
Sort of. If lookup of a name fails in the class, then lookup is continued in the base class.
10.2 Member name lookup
...
5 Otherwise (i.e., C does not contain a declaration of f or the resulting declaration set is empty), S(f,C) is initially empty. If C has base classes, calculate the lookup set for f in each direct base class subobject Bi, and merge each such lookup set S(f,Bi) in turn into S(f,C).
Member name lookup includes lookup of nested types too. Later in that same section, we find:
9 [ Note: A static member, a nested type or an enumerator defined in a base class T can unambiguously be found even if an object has more than one base class subobject of type T. Two base class subobjects share the non-static member subobjects of their common virtual base classes. —end note ]

C++ CRTP virtual function point of instantiation

I'm trying to understand if a simple CRTP pattern is valid by the standard.
The code below compiles and works as expected (on clang).
But my understanding of the relevant standard chapters/paragraphs is that
the point of instantiation of the virtual function CRTP< Derived, Base >::DoSomething()
should be at point (B) of the code, where the full declaration of Derived is not available.
Therefore the inner typedef Type should not be available either.
Can anyone kindly point out the relevant standard chapter that validates this code?
In other words, something that says that in this case the virtual function is instantiated
ATFER point C?
Thanks a lot in advance for any insight.
Francesco
//-------------------------
// START CODE
#include <iostream>
struct Type1 {};
struct Type2 {};
struct Base
{
virtual ~Base() {}
virtual void DoSomething() = 0;
};
template< typename T, typename U >
struct CRTP : U
{
virtual void DoSomething() { DoSomething( typename T::Type() ); }
void DoSomething( Type1 ) { std::cout << "1\n"; }
void DoSomething( Type2 ) { std::cout << "2\n"; }
};
// (A) point of inst. of CRTP< Derived, Base > ( 14.7.1.4 ) ??
// (B) point of inst. of CRTP< Derived, Base >::DoSomething() (14.6.4.1.4 ) ??
struct Derived : CRTP< Derived, Base >
{
typedef Type2 Type;
};
// (C)
int main()
{
Base * ptr = new Derived;
ptr->DoSomething();
delete ptr;
}
// END CODE
//-------------------------
Relevant (?) standard paragraphs:
14.6.4.1
4 If a virtual function is implicitly instantiated, its point of instantiation is immediately following the point of instantiation of its enclosing class template specialization.
14.7.1
4 A class template specialization is implicitly instantiated if the class type is used in a context that requires a completely-defined object type or if the completeness of the class type might affect the semantics of the program.
14.7.1
9 An implementation shall not implicitly instantiate a function template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instan- tiation. It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated.
This appears to be a result of the compiler delaying instantiation of CRTP<Derived, Base>::DoSomething() until the end of the translation unit, as it is allowed to do (see CWG issue 993).
CRTP<Derived, Base> is definitely instantiated right before the definition of Derived (§14.6.4.1 [temp.point]/p4, all quotes are to N3936):
For a class template specialization, a class member template
specialization, or a specialization for a class member of a class
template, if the specialization is implicitly instantiated because it
is referenced from within another template specialization, if the
context from which the specialization is referenced depends on a
template parameter, and if the specialization is not instantiated
previous to the instantiation of the enclosing template, the point of
instantiation is immediately before the point of instantiation of the
enclosing template. Otherwise, the point of instantiation for such a
specialization immediately precedes the namespace scope declaration or
definition that refers to the specialization.
Whether CRTP<Derived, Base>::DoSomething() is required to be instantiated at all depends on the meaning of the phrase referenced in a context that requires the member definition to exist (§14.7.1 [temp.inst]/p2). All non-pure virtual functions are odr-used (§3.2 [basic.def.odr]/p2), and "every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program" (§3.2 [basic.def.odr]/p4); whether that counts as "referenced in a context that requires the member definition to exist" is unclear.
(Even if it's not required to be instantiated, however, the compiler is still free to instantiate it per §14.7.1 [temp.inst]/p11 - "It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated.".)
If CRTP<Derived, Base>::DoSomething() is indeed instantiated, then the situation is covered by §14.6.4.1 [temp.point]/p5 and p8 (emphasis mine):
5 If a virtual function is implicitly instantiated, its point of
instantiation is immediately following the point of instantiation of
its enclosing class template specialization.
8 A specialization for a function template, a member function template,
or of a member function or static data member of a class template may
have multiple points of instantiations within a translation unit, and
in addition to the points of instantiation described above, for any
such specialization that has a point of instantiation within the
translation unit, the end of the translation unit is also considered a
point of instantiation. A specialization for a class template has at
most one point of instantiation within a translation unit. A
specialization for any template may have points of instantiation in
multiple translation units. If two different points of instantiation
give a template specialization different meanings according to the one
definition rule (3.2), the program is ill-formed, no diagnostic
required.
That is, it has two points of instantiation, one right after CRTP< Derived, Base >'s point of instantiation, and one at the end of the translation unit. In this case, at the two points of instantiations name lookup for typename T::Type would produce different results, so the program is ill-formed, no diagnostic required.
The use of new Derived causes the Derived class to be instantiated.
Correction: Derived is not itself a template, so its structure layout and contained member declarations are needed right away. That causes CRTP<Derived,Base> to be instantiated immediately following the Derived definition. I'll have to look up the formal standard later when I have more time; but the the point is still that the instantiation of CRTP only figures out the structure and available members, not the bodies of the member functions; and it knows the structure and members of the Derived class when it does so.
The member functions are not instantiated until they are used (here, the constructor), and it already has the class itself at that time. The other thing to look up is whether the constructor of Derived, since it is not a template, is generated immediately following the class, or only if/when needed. If the former, it can be made lazy by making Derived a template with a dummy argument. But that doesn't affect this specific question: whether right after Derived or right after main, the function instantiation is still not before parsing the declaration of Derived.
That causes CRTP<Derived,Base> to be instantiated. But in both cases it is only the class structure that is needed, not the actual code for any of the members. Erase all the inline function bodies, and you'll see there is no problem at this point.
Now the Derived default constructor is used, so Derived::Derived() is implicitly instantiated. The point of instantiation is immediately following the definition of main.
In instantiating Derived::Derived(), it then needs CRTP<Derived,Base>::CRTP(). It is instantiated at the same point as the template instantiation that needed it. That constructor needs all the virtual functions, so DoSomething() is instantiated, again, at the same point as the instantiation that kicked it off. You can see that all this happens well after the complete definition of the fully rendered Derived class is known, in terms of all the declarations of all the members (not the function bodies).
That's the missing insight: the class definition does not include member function definitions, even if they are given within the lexical enclosing region of the class definition. Remember the distinction between definitions and declarations, separately for classes and functions.

Do Explicit Instantiations of C++ Class Templates Instantiate Dependent Base Classes?

I figured an explicit instantiation request would automatically instantiate all base class members also, but I get a linker error: unresolved external symbol "public: void Base<int>::foo(int)" when building this code using Visual Studio 2008 or 2010.
Note that adding a call to foo() inside bar() forces the compiler to instantiate Base<int>::bar() and the build succeeds, so it appears that the compiler has all the necessary information to instantiate foo().
Obviously, explicitly instantiating Base<int> in source.cpp allows the build to succeed, but it seems silly to need to explicitly instantiate any dependent base classes whenever explicitly instantiating a derived class.
Is this normal? I couldn't find what the standard says regarding this issue.
header.h
template<typename T>
class Base {
public:
void foo();
};
template<typename T>
class Derived : public Base<T> {
public:
void bar();
};
source.cpp
#include "header.h"
template<typename T>
void Base<T>::foo() { }
template<typename T>
void Derived<T>::bar() {
// this->foo(); // adding this forces instantiation of foo()???
}
template class Derived<int>;
main.cpp
#include "header.h"
int main() {
Derived<int> d;
d.foo(); // Linker Error: unresolved external symbol "public: void Base<int>::foo(int)"
}
Edit:
It looks like the Standard says only members of a class get instantiated by an explicit class instantiation, so the linker error is justified in my example.
Note that a class is defined by class-head { member-specification } and "The member-specification in a class definition declares the full set of members of the class; no member can be added elsewhere." So members are only between the curly braces { }, and public base class members don't become members of the derived class, they are merely accessible from the derived class or by objects of the derived class.
My only remaining question is why the Standard specifies that explicit instantiation of a class template only instantiates members and not members of base classes? My guess is that this allows greater control of what gets explicitly instantiated where. Someone that's using explicit template class instantiations would most likely have the base class definitions in a different file than the derived class definitions, and would explicitly instantiate each separately.
The Standard says
The explicit instantiation of a class template specialization implies the instantiation of all of its members not previously explicitly specialized in the translation unit containing the explicit instantiation.
In other words, it does not mandate that base classes are explicitly instantiated in turn. It will cause an implicit instantiation of them which will not instantiate their member definitions up-front. It's some ugly glitch in the Standard as to whether some text when it says "member" means "direct" or "inherited" member, as that often seems to be "obvious" to the one who wrote the Standards wording, but not to the one who reads it. C++0x has added some clarifications (it also has a difference between explicit instantiation declarations and definitions that C++03 doesn't have, but even ignoring that, the C++0x wording contains some more bits of insight):
An explicit instantiation that names a class template specialization is also an explicit instantiation of the
same kind (declaration or definition) of each of its members (not including members inherited from base
classes) that has not been previously explicitly specialized in the translation unit containing the explicit
instantiation, except as described below. [ Note: In addition, it will typically be an explicit instantiation of
certain implementation-dependent data about the class. — end note ]