Re: C++ Templates: The Complete Guide
Comeau is OK with the OP's code if you move the int definition.
Code:
#include <iostream>
using namespace std;
// maximum of two int values
inline int const& max (int const& a, int const& b)
{
cout << "inline int const& max (int const& a, int const& b)" << endl;
return a < b ? b : a;
}
// maximum of two values of any type
template <typename T>
inline T const& max (T const& a, T const& b)
{
cout << "inline T const& max (T const& a, T const& b)" << endl;
return a < b ? b : a;
}
// maximum of three values of any type
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
cout << "inline T const& max (T const& a, T const& b, T const& c)" << endl;
return max (max(a,b), c); // uses the template version even for ints
} // because the following declaration comes
// too late:
int main()
{
int a, b, c;
a = 1; b = 2; c = 3;
max(a,b,c);
getchar();
return 0;
}
It's also happy if you move the int definition and change it to a specialised function template.
Code:
// maximum of two int values
template <>
inline int const& max<int>(int const& a, int const& b)
{
std::cout << "inline int const& max (int const& a, int const& b)" << std::endl;
return a < b ? b : a;
}
Though you must remove the using namespace std; otherwise the STL max definitions conflict.
Re: C++ Templates: The Complete Guide
Can anyone test what the above variations do under GCC?
Both variants give the output below, under VS2008.
inline T const& max (T const& a, T const& b, T const& c
inline int const& max (int const& a, int const& b)
inline int const& max (int const& a, int const& b)
Note: It's better to name the functions other than 'max' as this alleviates any possibility of compilation weirdness do to conflict with other 'max' definitions.
Re: C++ Templates: The Complete Guide
Quote:
Originally Posted by JohnW@Wessex
Can anyone test what the above variations do under GCC?
Both variants give the output below, under VS2008.
inline T const& max (T const& a, T const& b, T const& c
inline int const& max (int const& a, int const& b)
inline int const& max (int const& a, int const& b)
I get the same output with the MinGW port of g++ 3.4.5.
Quote:
Originally Posted by JohnW@Wessex
Note: It's better to name the functions other than 'max' as this alleviates any possibility of compilation weirdness do to conflict with other 'max' definitions.
We could just fully qualify each use of max.
Re: C++ Templates: The Complete Guide
So what's the verdict on this?
With STL name clashes eliminated and function declarations slightly re-ordered, Comeau compiles OK and VS2008 & GCC agree on the functions that are actually executed.
Do we agree that this is compliant behaviour?
Re: C++ Templates: The Complete Guide
i think you're missing the point of my question. Reordering is not a solution, as i shouldnt need to re-order anything to follow along with the book. The problem is not being able to follow along with the examples and techniques as they are written.
I really dont know what to do about this. I could just work with the way VS does it, and it be non portable or i can change compiler. I dont think trying to write compliant code under VS is a viable option as its never going to tell me about the non compilant mistakes i happen to make along the way, and then when i do come to port it, i'll have to make appropiate fixes, or find subtle bugs.
Re: C++ Templates: The Complete Guide
Quote:
Originally Posted by
wheelie
i think you're missing the point of my question. Reordering is not a solution
I understand your original question, I just was curious as to whether the re-ordered code was valid or invalid too.
The re-ordered code makes the execution of the code identical in VS2008 and GCC where before in wasn't.
Pasting your original code into Comeau (generally believed to be the most compliant), after changing 'max' to 'maximum' to avoid name clashes with the STL, results in zero errors.
Code:
#include <iostream>
using namespace std;
// maximum of two values of any type
template <typename T>
inline T const& maximum (T const& a, T const& b)
{
cout << "inline T const& maximum (T const& a, T const& b)" << endl;
return a < b ? b : a;
}
// maximum of three values of any type
template <typename T>
inline T const& maximum (T const& a, T const& b, T const& c)
{
cout << "inline T const& maximum (T const& a, T const& b, T const& c)" << endl;
return maximum (maximum(a,b), c); // uses the template version even for ints
} // because the following declaration comes
// too late:
// maximum of two int values
inline int const& maximum (int const& a, int const& b)
{
cout << "inline int const& maximum (int const& a, int const& b)" << endl;
return a < b ? b : a;
}
int main()
{
int a, b, c;
a = 1; b = 2; c = 3;
maximum(a,b,c);
getchar();
return 0;
}
Quote:
In strict mode, with -tused, Compile succeeded
So the question is, who is correct?
The book or VS2008 / GCC / Comeau?
I don't know.
Re: C++ Templates: The Complete Guide
Quote:
Originally Posted by
wheelie
Reordering is not a solution, as i shouldnt need to re-order anything to follow along with the book. The problem is not being able to follow along with the examples and techniques as they are written.
Your doubt about the book started when you didn't follow the book properly,
and we cleared that part up for you.
Quote:
I could just work with the way VS does it, and it be non portable or i can change compiler.
What you bring to the discussion - the compliance discrepency among the compiler - is nothing new.
You should've known this when you were a beginner
Code:
#include <string>
int main()
{
std::string str("Cow");
str.erase(str.end());
}
not at the learning curve where you bought the book to "futher the understanding."
When Josuttis gave his example on type designation in templates,
did he mention the name of the compiler?
Did he say, "typename required on MSVS compiler?"
If not, why are you turning everything you found in his work on one particular compiler and judge his whole work?
Quote:
I really dont know what to do about this
You should draw your own conculsion
Few days passed and not a single word of educated opinions on your part as to what you think should happen. What gives!
Do you think non-template version should've been called? or the template version?
What are the arguments behind that choice?
EDIT:
So, let's share our educated opinion to reach some conclusion
I'll start first.
Q. In C++, which happens first? type checking or name look up?
Re: C++ Templates: The Complete Guide
Quote:
Your doubt about the book started when you didn't follow the book properly,
and we cleared that part up for you.
Where did you clear it up? If you're refering to your reply on the using namespace problem, i reposted the code without the using namespace and got the exact same result.
Quote:
If not, why are you turning everything you found in his work on one particular compiler and judge his whole work?
I thought id been quite clear on this, ..... Im not judging his work at all, im not saying he is wrong or anything like that, .. I'm simply wondering how to continue with the book, when Visual Studio is the compiler ive been using for so long.
Quote:
You should draw your own conculsion
Few days passed and not a single word of educated opinions on your part as to what you think should happen. What gives!
Do you think non-template version should've been called? or the template version?
What are the arguments behind that choice?
I think that the way Joshuttis explains makes the most sense, in that yes the non template functions should be called first, but they cant in this case because they havent been seen yet. The fact that it doesnt go this way in Visual Studio was the whole point of this thread.
Re: C++ Templates: The Complete Guide
Quote:
Originally Posted by
wheelie
I think that the way Joshuttis explains makes the most sense, in that yes the non template functions should be called first, but they cant in this case because they havent been seen yet.
Looking at the code, I expected that the integer version would be called because by the time the compiler parses 'main', which is the first place that 'max' is invoked, it has seen both the int and template definitions. Therefore the compiler would use the 'best fit', which would be the int version. So, from my reasoning, the Visual Studio execution of the code was perfectly logical.
My logic may not coincide with that of the C++ Standard creators. :rolleyes:
Re: C++ Templates: The Complete Guide
Hmm, i see what you're saying. But if i was to write
Code:
//void Func1();
void Func2()
{
Func1();
}
void Func1()
{
}
int main()
{
Func2();
return 0;
}
Its clearly an error, unless i uncomment out the declaration. And having it uncommented is the same as what you thought should logically compile. The way that VS is getting away with it, i assume is due to the double comiling that template compilation goes through.
Once for Syntax Check
Second time round for instantiation
So when VS compiles it, it also keeps track over the declarations its read, for the second pass.
I think GCC does the same, just doesnt remember the declarations from the first pass. So order is therefore important. Thats my thinking, not sure if its correct.
Re: C++ Templates: The Complete Guide
But there is a difference in that the your original example contains template definitions. The compiler doesn't actually have to generate any code until it finds a place where they are required. I've found errors in a couple of my templates, a long time after I wrote them, because I hadn't created any code that actually used them until then.
From what I can see, when the compiler parses max(a, b, c) it generates the code from the three parameter template with int as the type. As it generates the code, it finds a call to max with two int parameters and has the choice between the templated version or the 'int' version. The int version is the better match.
Whether that's how it should work is another matter, but it seems logical to me.
Re: C++ Templates: The Complete Guide
Quote:
Originally Posted by
JohnW@Wessex
Looking at the code, I expected that the integer version would be called because by the time the compiler parses 'main', which is the first place that 'max' is invoked, it has seen both the int and template definitions. Therefore the compiler would use the 'best fit', which would be the int version.
Yes, according to the lookup rules, the compiler will choose the non-templated version over the templated version.
Regards,
Paul McKenzie
Re: C++ Templates: The Complete Guide
Quote:
Looking at the code, I expected that the integer version would be called because by the time the compiler parses 'main', which is the first place that 'max' is invoked, it has seen both the int and template definitions
Yes, but i believe that problem is not whether main has seen the int version, but whether the max template further up has. Which is why is doesnt work with GCC.
max(a,b)
max(a,b,c)
max(int, int);
As Joshutis explains, becuase max(a,b,c) hasnt seen max(int,int), it can only use max(a,b). That is unless you use Visual studio.
Quote:
Yes, according to the lookup rules, the compiler will choose the non-templated version over the templated version.
Only if its been seen though, which in this case, it hasnt. max(a,b,c) has only seen max(a,b), so that is the only template or function it can use.
Re: C++ Templates: The Complete Guide
Quote:
Originally Posted by
JohnW@Wessex
So what's the verdict on this?
With STL name clashes eliminated and function declarations slightly re-ordered, Comeau compiles OK and VS2008 & GCC agree on the functions that are actually executed.
Do we agree that this is compliant behaviour?
If my vote counts, I think it is (for the one with template specialization)
Quote:
Originally Posted by wheelie
As Joshutis explains, becuase max(a,b,c) hasnt seen max(int,int), it can only use max(a,b). That is unless you use Visual studio.
I think the order in which the overloaded functions appear shouldn't really matter
becase of all the look up rules, and not to mention how it would be impractical to design such a set if it did.
So I'm all for Paul's first observation that anything can happen with a code such as the OP,
or, at best, overloading template and non template in this way is compiler dependant
since the responsibility of generating the right code lies on the compiler, not us.
so I'll say this again, prefer template specialization over it!
And a reputation for wheelie for recognizing this issue :thumb:
Re: C++ Templates: The Complete Guide
Quote:
Originally Posted by
potatoCode
So I'm all for Paul's first observation that anything can happen with a code such as the OP,
or, at best, overloading template and non template in this way is compiler dependant
since the responsibility of generating the right code lies on the compiler, not us.
so I'll say this again, prefer template specialization over it!
And a reputation for wheelie for recognizing this issue :thumb:
Well the order doesnt seem to matter in Visiual Studio, but Joshuttis specifically mentions that the order does matter
Quote:
// uses the template version even for ints
// because the following declaration comes
// too late:
I think im going to play around with this some more, becuase if the order does matter, then that goes against one of herb sutters articles too.
http://www.gotw.ca/publications/mill17.htm
That is unless order *after* name lookup for finding more specialised functions matters. Gah ! its all getting very complicated :P :)