c++ compiler behaviour using template class [duplicate] - c++

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Two phase lookup - explanation needed
When I'm using a template class the compiler doesn't show me errors/warning of missing #includes.
For example, If I have a class called "A" and it looks much or less like this :
template<class T>
class A {
void print() const {cout << "Hey I didn't use include for
iostream and It works just fine!!!";}
};
If I remove the template < class T > I get errors of the absence of <iostream >include.
Why the compiler doesn't show these errors when I'm using template class ?
Just to point out, when I say It works I mean It doesn't show me any compilation errors when I'm writing the class but only when I use it as opposed to a non-template class whereas the error shows immediately.

When you write template code, a huge bulk of the syntax checking happens only if and when you make an instance of this class, if it is never used, it is never checked.
To verify this, add this line at the end, A<int>;
More information at Two phase lookup - explanation needed as jrok points out.
Edit:
The linked posts bring up an interesting point, this does error out on gcc and clang even without an instantiation. I guess like myself, you are on MSVC++

When the compiler first parses your template, it is only required to perform the most basic syntax checks and type checking for non-dependent types (types which are not defined in terms of the template arguments). For each member function of a fully specialized templated type, all type-checking on dependent types (those that depend on template arguments) only needs to be done the first time it comes across an expression using that function (for example by calling it). This also means that any member function you don't use (for a particular specialization) of a templated type might not be fully compiled at all.
This is called two-phase name lookup and (as mentioned in the other answers) you can find more information about it here: Two-phase lookup

Related

Why is plain old function not selected for explicit call? [duplicate]

What does it mean that compiler is using two phase lookup in order to compile template class?
Templates are compiled (at least) twice:
Without Instantiation the template code itself is checked for syntax.
Eg: Any syntax errors such as ; etc.
At the time of instantiation(when the exact type is known), the template code is checked again to ensure all calls are valid for that particular type.
Eg: The template might in turn call to functions which might not be present for that particular type.
This is called as Two Phase Lookup.

How does a parser for C++ differentiate between comparisons and template instantiations?

In C++, the symbols '<' and '>' are used for comparisons as well as for signifying a template argument. Thus, the code snippet
[...] Foo < Bar > [...]
might be interpreted as any of the following two ways:
An object of type Foo with template argument Bar
Compare Foo to Bar, then compare the result to whatever comes next
How does the parser for a C++ compiler efficiently decide between those two possibilities?
If Foo is known to be a template name (e.g. a template <...> Foo ... declaration is in scope, or the compiler sees a template Foo sequence), then Foo < Bar cannot be a comparison. It must be a beginning of a template instantiation (or whatever Foo < Bar > is called this week).
If Foo is not a template name, then Foo < Bar is a comparison.
In most cases it is known what Foo is, because identifiers generally have to be declared before use, so there's no problem to decide one way or the other. There's one exception though: parsing template code. If Foo<Bar> is inside a template, and the meaning of Foo depends on a template parameter, then it is not known whether Foo is a template or not. The language standard directs to treat it as a non-template unless preceded by the keyword template.
The parser might implement this by feeding context back to the lexer. The lexer recognizes Foo as different types of tokens, depending on the context provided by the parser.
The important point to remember is that C++ grammar is not context-free. I.e., when the parser sees Foo < Bar (in most cases) knows that Foo refers to a template definition (by looking it up in the symbol table), and thus < cannot be a comparison.
There are difficult cases, when you literally have to guide the parser. For example, suppose that are writing a class template with a template member function, which you want to specialize explicitly. You might have to use syntax like:
a->template foo<int>();
(in some cases; see Calling template function within template class for details)
Also, comparisons inside non-type template arguments must be surrounded by parentheses, i.e.:
foo<(A > B)>
not
foo<A > B>
Non-static data member initializers bring more fun: http://open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#325
C and C++ parsers are "context sensitive", in other words, for a given token or lexeme, it is not guaranteed to be distinct and have only one meaning - it depends on the context within which the token is used.
So, the parser part of the compiler will know (by understanding "where in the source it is") that it is parsing some kind of type or some kind of comparison (This is NOT simple to know, which is why reading the source of competent C or C++ compiler is not entirely straight forward - there are lots of conditions and function calls checking "is this one of these, if so do this, else do something else").
The keyword template helps the compiler understand what is going on, but in most cases, the compiler simply knows because < doesn't make sense in the other aspect - and if it doesn't make sense in EITHER form, then it's an error, so then it's just a matter of trying to figure out what the programmer might have wanted - and this is one of the reasons that sometimes, a simple mistake such as a missing } or template can lead the entire parsing astray and result in hundreds or thousands of errors [although sane compilers stop after a reasonable number to not fill the entire universe with error messages]
Most of the answers here confuse determining the meaning of the symbol (what I call "name resolution") with parsing (defined narrowly as "can read the syntax of the program").
You can do these tasks separately..
What this means is that you can build a completely context-free parser for C++ (as my company, Semantic Designs does), and leave the issues of deciding what the meaning of the symbol is to a explicitly seperate following task.
Now, that task is driven by the possible syntax interpretations of the source code. In our parsers, these are captured as ambiguities in the parse.
What name resolution does is collect information about the declarations of names, and use that information to determine which of the ambiguous parses doesn't make sense, and simply drop those. What remains is a single valid parse, with a single valid interpretation.
The machinery to accomplish name resolution in practice is a big mess. But that's the C++ committee's fault, not the parser or name resolver. The ambiguity removal with our tool is actually done automatically, making that part actually pretty nice but if you don't look inside our tools you would not appreciate that, but we do because it means a small engineering team was able to build it.
See an example of resolution of template-vs-less than on C++s most vexing parse done by our parser.

Why my C++ templated function does not produce `undeclared identified` compile error?

I am trying to create an abstraction about Lights (I'm building a game in C++) and I'm using templates to do that. A part of my code right now is:
// Light.hpp
template <typename LightType>
void LoadLight(GLuint shaderId, const LightType& light, const std::string& glslUniformName)
{
// Load common light attributes
glUniform3f(glGetUniformLocation(lightingShader.GetProgID(), (glslUniformName + ".ambient").c_str()), light.ambient.x, light.ambient.y, light.ambient.z);
glUniform3f(glGetUniformLocation(lightingShader.GetProgID(), (glslUniformName + ".diffuse").c_str()), light.diffuse.x, light.diffuse.y, light.diffuse.z);
glUniform3f(glGetUniformLocation(lightingShader.GetProgID(), (glslUniformName + ".specular").c_str()), light.specular.x, light.specular.y, light.specular.z);
// Load specific light attributes
LoadLightSpecific<LightType>(shaderId, light, glslUniformName); // ???
}
template <typename LightType>
void LoadLightSpecific(GLuint shaderId, const LightType& light, const std::string& glslUniformName);
The specializations for LoadLightSpecific is on a separate .cpp file which is irrelevant with my question.
My problem is in the line with the ???.
I am using LoadLightSpecific before I define it! I thought that this would give me a undeclared identifier (or something like that) compile error but no. It works normally.
Why is that happening? I feel like I am missing something obvious.
Update 23/11/2015
So, as people recommended in comments I used Wandbox to recreate the problem with minimal code. I ended up here. Apparently, the answer to my question seems to be:
"The code should not compile but somehow MSVC works his way around the problem"
It is not unusual with templates that when writing them, you assume something about the template arguments. i.e:
Template<class T>
class C
{
void foo() { T.bar(); }
};
Even though we dont know if T will actually have a method bar(), the compiler accepts it at the moment, because it is just a "template", not actual code. At the time when you instantiate a template, with some arguments, the compiler will check for the correctness of what you assumed, because now it has to generate code.
In the case of functions it is the same. The same logic must apply unless somebody finds an explicit statement about it in the standard, which I tried to find and didn't.
If we follow this logic, when you wrote the template of LoadLight, you assumed that there exists such a function called LoadLightSpecific<T>. In other words,
Why would T.bar() and bar<T>() be accepted in a class template, but not in a function template?
The templated function is not translated at the place of its templated definition, but when it is actually called (similar to the instantiation of a templated class) with some specific template argument. If at that place, all what is needed is available (LoadLightSpecific declared), then it will work fine.
However, I think that it is good practice to, as much as possible, have things declared at the place of the template definition. This will make it easier to track the dependencies.
For this particular code:
If there's a function template called LoadLightSpecific in scope at the point of definition, then this template definition is valid by itself. (It doesn't have to have that signature; even template<int> void LoadLightSpecific(); will do.)
The reason for this is that the compiler must know LoadLightSpecific is a template in order to parse the < as the start of a template argument list, rather than the less-than operator.
Since LoadLightSpecific<LightType>, if parsed as a template-id, is dependent on a template parameter, name lookup for LoadLightSpecific is postponed until instantiation. (Note that this does not mean instantiation will necessarily succeed: a declaration that is not in the template definition context can only be found in the instantiation context by ADL, not by normal unqualified lookup.)
In the more general case, the standard specifies what names are considered dependent on a template parameter and what aren't. Non-dependent names are looked up and bound at the point of template definition:
If a name does not depend on a template-parameter (as defined in
14.6.2), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template
definition; the name is bound to the declaration (or declarations)
found at that point and this binding is not affected by declarations
that are visible at the point of instantiation.
MSVC is well-known for its nonconformance in this area.

C++ How do compilers handle templates [duplicate]

This question already has answers here:
How does the compilation of templates work?
(7 answers)
Closed last year.
As some of you may know from my recent posts i am studying for a C++ exam which the content for the class was delivered very poorly. I am basically having to self teach everything myself so bear with me here.
This is an exam question:
(i)Explain the concepts of templates as defined in the C++ language.
Be sure to differentiate between what the programmer does and what the
compiler does.
My current rationale:
(i) A template allows a function or class to operate using generics. This allows the programmer to effective program X functionality once, and be able to use this functionality with many different data types without having to rewrite the application or parts of the application multiple times.
My problem is i have no idea how the compiler handles the use of templates.
I am unsure what the compiler does at this stage, if somebody could clear this up it would be helpful.
Templates in C++ are implemented through substitution. It's not like Java generics which just type check the code which involves the generics class and then compiles it using raw references (type erasure).
Basically C++ creates a different class/method for each actual template argument used in your code. If you have your
template<typename T>
void myMethod(T t)
{
//
}
what happens at compile time is that a different method is compiled for each type the template is actually used. If you use it on myMethod(50) and myMethod("foo") then two overloaded version of the method will be available at runtime. Intuitively this means that templates could generate code bloating but in practice the same expressiveness is obtained by a larger codebase without templates with less readability so that's not a real concern.
So there is no black magic behind them (ok there is if you consider meta programming or partial specialization).
let's say you write a function using templates:
template <typename T>
void function(T t){
doSomething();
}
for each data type you call this function, the compiler simply replaces the 'T' with that data type, say 'int' and generates code for that like you've written this function with 'int' instead of 'T' since the beginning.
This is probably the right (but not the complete) answer if others agreed.
For each instance of an object of a different type that you create or in case of functions the different type of arguments that you use, the compiler simply makes an overloaded version at compile time. So if you have a template function like a sort function and use that function for int and double arrays, then the compiler have actually made two functions: one using int and the other using double. This is the simplest explanation I could give. Hope it's useful.

iphone compiler inherited templated base classes with passed through type not being expanded in time (just look)

Try this out:
template <typename T>
class Base
{
public:
int someBaseMember;
};
template <typename T>
class Test: public Base<T>
{
public:
void testFunc()
{
someBaseMember = 0;
}
};
In vc++ and the psp compiler (and any other compiler I've encountered) the above will work fine, with the iphone compiler (for device, gcc 4.2 I think, with the -fpermissive flag set) I get an error saying
'someBaseMember is not defined'
on the
'someBaseMember = 0;'
line
The iphone compiler seems to be 'parsing' templated code a lot sooner than other compilers do, (from what I can tell, most others don't even syntax check them until you actually CALL the function, or instantiate an instance.)
From what I can tell its parsing it so soon that it hasn't even parsed the base class yet :S its like it doesn't exist.
Any Ideas?
The error that you are getting is correct (the other compilers should not accept the code and are doing so erroneously); the variable someBaseMember depends on the template instantation of Base<T>, but this dependence has not been expressed in your usage, and hence the compiler is correct in attempting to resolve it independently of the template parameter.
You can resolve this problem by making this dependence explicit, thereby forcing the compiler to resolve the variable using the template instantation. You can use either of the following:
this->someBaseMember = 0;
OR
Base<T>::someBaseMember = 0;
Either of the above should result in the resolution mechanism you want.
EDIT
You might want to see the relevant section of the C++ FAQ Lite:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18
someBaseMember is a name that doesn't seem to depend on the template parameters, so it's not a dependent name, as the standard calls it.
The C++ name lookup rules cause the compiler to not look in the templated base class for this name, since it's not a dependent name. To work around this, you can use this-> to make clear that someBaseMember is a member of the class (and so implicitly dependent on the template parameters):
this->someBaseMember = 0;
This is not specific to the iphone compiler, but defined like that in the language. See also this entry in the C++ FAQ Lite for more details.