|
Only you can determine that. Unless you try it, you'll never know.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
|
By calling accept() and noting the client's name and port number that it returns.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hello everyone,
Why in the following code segment (along with Bjarne's comments), function get_new can not deduce template parameter type to be int by its return value assignment to int * p1, and deduce T* is int*, and so T is int (e.g. as we did for function release in the same sample below)?
class Memory {
public:
template <class T> T * get _new ();
template <class T > void release (T&);
/ / ...
};
template <class Allocator> void f (Allocator &m )
{
int * p1 = m.get _ new <int>();
operator
int * p2 = m.template get _ new <int>();
/ / ...
m.release (p1);
m.release (p2 );
}
Explicit qualification of get _new() is necessary because its template parameter cannot be deduced. In this case, the t e m p l a t e prefix must be used to inform the compiler (and the human reader) that get _new is a member template so that explicit qualification with the desired type of element is possible. Without the qualification with template , we would get a syntax error because the < would be assumed to be a less than operator. The need for qualification with template is rare because most template parameters are deduced.
thanks in advance,
George
|
|
|
|
|
I think template parameter cannot be deduced by its return value type for the same reason it is not allowed to overload methods based on return values, see point 5.7.8 of [^].
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
About,
CPallini wrote: template parameter cannot be deduced by its return value type
Is it C++ Spec regulated? Or vendor implementation specific?
About the link, it only deals with overload, not covering template, right?
regards,
George
|
|
|
|
|
George_George wrote: Is it C++ Spec regulated? Or vendor implementation specific?
AFAIK it is C++ specification (maybe I'm wrong).
George_George wrote: About the link, it only deals with overload, not covering template, right?
Yes. But there is a remarkable similarity.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
Do you know which section of Spec? I am interested to learn more details.
regards,
George
|
|
|
|
|
Oh no, it was more a guess than exact knowledge about.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks all the same, dude!
regards,
George
|
|
|
|
|
There is an exception to this rule: they are for casting operators. See the following example:
#include "stdafx.h"
#include <iostream>
using namespace std;
struct Magic
{
operator int() const
{
return 1;
}
operator double() const
{
return 1.234;
}
};
int main()
{
Magic m;
int i = m;
double d = m;
cout << "i=" << i << ", d=" << d << endl;
return 0;
}
Steve
|
|
|
|
|
yes steve, you are correct.
But, My understanding is "operator double()" and "operator int()" are not overloaded members instead it is two different overloaded operators for user-defined conversion of prototype "double operator double()" and "int operator int()" since conversion has the same return type of the conversion type the return type of the conversion operators are redundant and compiler gives error message "C2549: user-defined conversion cannot specify a return type" actually these functions differ not by return type but by the prototype itself.
|
|
|
|
|
Rajkumar R wrote: yes steve, you are correct.
But, My understanding is "operator double()" and "operator int()" are not overloaded members instead it is two different overloaded operators for user-defined conversion of prototype "double operator double()" and "int operator int()" since conversion has the same return type of the conversion type the return type of the conversion operators are redundant and compiler gives error message "C2549: user-defined conversion cannot specify a return type" actually these functions differ not by return type but by the prototype itself.
That's arguable. I'd consider them member functions since they have access to the object's state through an implicit this pointer. They definitely return something and the choice of which function is called depends on the type to which the result of the call is assigned.
Steve
|
|
|
|
|
Stephen Hewitt wrote: I'd consider them member functions since they have access to the object's state through an implicit this pointer
ofcourse both are member functions, I mean its not overloaded functions but different overloaded operators. (function overloading and operator overloading).
Stephen Hewitt wrote: and the choice of which function is called depends on the type to which the result of the call is assigned
both are different functions and its not matched by the return type but as a typecast operator.
|
|
|
|
|
Rajkumar R wrote: both are different functions and its not matched by the return type but as a typecast operator.
No explicit type cast is needed:
#include "stdafx.h"
#include <iostream>
using namespace std;
struct Magic
{
operator int() const
{
cout << "int" << endl;
return 0;
}
operator float() const
{
cout << "float" << endl;
return 0.0;
}
operator double() const
{
cout << "double" << endl;
return 0.0;
}
};
int main()
{
Magic m;
int i = m;
float f = m;
double d = m;
return 0;
}
Give it a try!
Steve
|
|
|
|
|
yes i know, this code is already there in your original reply.
Its implicit conversion.
|
|
|
|
|
We can argue semantics forever but the following remains: which function is called depends on the type the expression is assigned to.
Steve
|
|
|
|
|
Stephen Hewitt wrote: which function is called depends on the type the expression is assigned to.
That is the use of implicit typecast, when implicit typecast the compiler uses the operator of the type, not all the functions which return the type.
And also if a function returns int doesnot restrict to assign to a variable of type long. The function is matched with the prototype and return type is evaluated for the further assignment statement.
implicit typecast (or explicit), takes the corresponding operator and not all the function that returns the corresponding type.
|
|
|
|
|
Well, I agree with Rajkumar R they are, in fact, different methods and not overloads of the same method. However, I have to admit that, as you stated, it is arguable.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
|
Thanks Steve,
Your purpose of the sample shows conversion operator is an exception?
regards,
George
|
|
|
|
|
Yes. You can use this with templates too. From memory MSVC6 chokes on it with templates, but it's legal.
Steve
|
|
|
|
|
Thanks Steve,
Stephen Hewitt wrote: You can use this with templates too
You mean using template parameter (template type parameter) as return type for conversion operator?
regards,
George
|
|
|
|
|
Try this (it crashes on MSVC6, but I believe it should work on more standard compliant compilers):
#include "stdafx.h"
#include <iostream>
using namespace std;
struct Magic
{
template <typename T>
operator T() const
{
return 0.1234012340123401234;
}
};
int main()
{
Magic m;
int i = m;
float f = m;
double d = m;
cout << "i=" << i << ", f=" << f << ", d=" << d << endl;
return 0;
}
Steve
|
|
|
|
|
This is probably a better example:
#include "stdafx.h"
#include <iostream>
#include <typeinfo>
using namespace std;
struct Magic
{
template <typename T>
operator T() const
{
cout << typeid(T).name() << endl;
return T();
}
};
int main()
{
Magic m;
int i = m;
float f = m;
double d = m;
return 0;
}
Make sure RTTI is enabled for this one. Again, it crashes in MSVC6, but I believe it should work with more standard compliant compilers.
Steve
|
|
|
|