473,509 Members | 2,951 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

What's difference between f(const MyClass & in) and f(MyClass in)

If I define the following codes:

void f(const MyClass & in) {cout << "f(const)\n";}
void f(MyClass in) {cout<<"f()\n";}

MyClass myclass;
f(myclass);

Compiler complain that it can't find the best match. Anyone could give a
detail explanation in theory? Which one is good?

Thanks
Jul 23 '05 #1
11 2488

modemer wrote:
If I define the following codes:

void f(const MyClass & in) {cout << "f(const)\n";}
void f(MyClass in) {cout<<"f()\n";}

MyClass myclass;
f(myclass);

Compiler complain that it can't find the best match. Anyone could give a detail explanation in theory? Which one is good?

Well, which function do you think *should* get called? The answer is
"nobody knows". It could call either one, that's why the compiler
complains that it doesn't have a "best" match, because both matches are
the same.

Hope this helps,
-shez-

Jul 23 '05 #2
Thanks Shezan, what you said is what I found and that's why I asked this
question here, but I want to know if there is any discussion in C++ theory
about this? I am not good at reading C++ theory book :-)

if I say, these 2 funcs have same signature, I think it's wrong because
compiler should complain like "function has been defined".
if I say, these 2 funcs is overloaded, I think it's also not correct because
they are conflicting.
so I think C++ theory could discuss this situation and explain the reason.

I am not sure if my question is clear enough.

Thanks.
"Shezan Baig" <sh************@gmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...

modemer wrote:
If I define the following codes:

void f(const MyClass & in) {cout << "f(const)\n";}
void f(MyClass in) {cout<<"f()\n";}

MyClass myclass;
f(myclass);

Compiler complain that it can't find the best match. Anyone could

give a
detail explanation in theory? Which one is good?

Well, which function do you think *should* get called? The answer is
"nobody knows". It could call either one, that's why the compiler
complains that it doesn't have a "best" match, because both matches are
the same.

Hope this helps,
-shez-

Jul 23 '05 #3

"modemer" <me@privacy.net.invalid> wrote in message
news:d1**********@domitilla.aioe.org...
If I define the following codes:

void f(const MyClass & in) {cout << "f(const)\n";}
void f(MyClass in) {cout<<"f()\n";}

MyClass myclass;
f(myclass);

Compiler complain that it can't find the best match. Anyone could give a
detail explanation in theory? Which one is good?

Thanks

The problem is that the syntax for calling those is the same. Given the
first function, which takes a const reference, you call it by passing an
instance of the class. Given the second function, which gets its parameter
by value (making a copy as it does so), you also cll it by passing an
instance of the class. So, when the compiler sees you calling the function
by passing an instance, which function should be called?

I've never seen an instance where I need to have both versions of such a
function available. Why do you need them both?

If they do different things, then perhaps they should have different
names...?

If they do the same exact thing, then why have two of them? Pick whichever
you prefer and remove the other one.

I also wonder why the compiler allows you to declare two functions which
will later lead to an inability to pick the best match. Perhaps there is a
way to construct a call to one that will not appear to be a call to the
other? I don't know off-hand, but as I said, I simply don't do that anyway,
so the issue never comes up.

As for which is best, it may or may not matter. If you have an object for
which copying is costly, then you may prefer to pass by const reference,
since it does not make a copy. However, if you only call this function once
in a blue moon, the overall performance cost may be negligible in practice,
even if it is costly on a per-instance basis.

I tend to prefer the const reference, as a habit mostly, unless what I'm
passing is a built-in type, in which case I pass by value. But that's just
me.

-Howard


Jul 23 '05 #4
I'll just add that if the copy constructor or destructor of MyClass has
side effects, those side effects will happen with the ' void f(MyClass
in) {cout<<"f()\n";} ' version but not with the other.

This version makes a copy of the argument for the function, while the
const reference one doesn't. To illustrate:

class MyClass
{
public:
MyClass() { cout << "Constructor!\n"; }
MyClass(const MyClass& i) { cout << "Copy Constructor!\n"; }
virtual ~MyClass() { cout << "Destructor!\n"; }
};
void f1(MyClass in) {cout<<"f()\n";}
void f2(const MyClass &in) {cout<<"f()\n";}

int main()
{
MyClass a;

cout << "*** About to call f1:\n";
f1(a);
cout << "*** About to call f2:\n";
f2(a);
cout << "*** Done with call to f2\n";
}

Gives the following output:
Constructor!
*** About to call f1:
Copy Constructor!
f()
Destructor!
*** About to call f2:
f()
*** Done with call to f2
Destructor!

For this reason, moreso than the efficiency boost (though that is
always nice), I prefer the const reference if you have the choice: it
seems safer somehow.
To the original question, I also don't know why it allows both
functions. Visual C++ doesn't give an error on the second declaration,
only an "ambiguous call to an overloaded function" error at the call to
f. I also tried making the object I passed to the class const to see if
that would make it prefer the const reference, but no go.

My guess is that it's just too difficult to be sure that the call will
*always* be ambiguous.

(Other ambiguous calls can be resolved some of the time though. For
instance, the following code results in an ambigious call error:
void f(float a) {cout<<"a()\n";}
void f(double b) {cout<<"b()\n";}

int main()
{
f(1);
}
But this could of course be easily resolved by casting the argument to
a float/double.)

Jul 23 '05 #5
Howard,
I also wonder why the compiler allows you to declare two functions which
will later lead to an inability to pick the best match.
Good point! I think you clarified my question.
We know C++ is strong type checking language, but at this point, seems it
doesn't work so well.Nobody could say "const Type &" and "Type" is same
type, thus C++ standard should:

1. either rules out one of them allowed existing in same scope, i.e.
compiler should raises an error like "conflict defination" instead of
current "can't find a best match"

2. or allows both of them existing, and called with certain modifier, for
example:

void f(const MyClass & in) {cout << "f(const)\n";}
void f(MyClass in) {cout<<"f()\n";}

MyClass myclass;
f(myclass&); // this syntex will lead to call f(const MyClass & in)
f(myclass); // this syntex will lead to call f(MyClass in)

I know, probably "f(myclass&);" would be hard or impossible to be
implemented with the concerning overall of syntex parsing of the operator
"&", this is why I hope C++ theory has already analyzed this scenario.
anyone has ever seen this analysis?
"Howard" <al*****@hotmail.com> wrote in message
news:sP*********************@bgtnsc04-news.ops.worldnet.att.net...
"modemer" <me@privacy.net.invalid> wrote in message
news:d1**********@domitilla.aioe.org...
If I define the following codes:

void f(const MyClass & in) {cout << "f(const)\n";}
void f(MyClass in) {cout<<"f()\n";}

MyClass myclass;
f(myclass);

Compiler complain that it can't find the best match. Anyone could give a
detail explanation in theory? Which one is good?

Thanks

The problem is that the syntax for calling those is the same. Given the
first function, which takes a const reference, you call it by passing an
instance of the class. Given the second function, which gets its

parameter by value (making a copy as it does so), you also cll it by passing an
instance of the class. So, when the compiler sees you calling the function by passing an instance, which function should be called?

I've never seen an instance where I need to have both versions of such a
function available. Why do you need them both?

If they do different things, then perhaps they should have different
names...?

If they do the same exact thing, then why have two of them? Pick whichever you prefer and remove the other one.

I also wonder why the compiler allows you to declare two functions which
will later lead to an inability to pick the best match. Perhaps there is a way to construct a call to one that will not appear to be a call to the
other? I don't know off-hand, but as I said, I simply don't do that anyway, so the issue never comes up.

As for which is best, it may or may not matter. If you have an object for
which copying is costly, then you may prefer to pass by const reference,
since it does not make a copy. However, if you only call this function once in a blue moon, the overall performance cost may be negligible in practice, even if it is costly on a per-instance basis.

I tend to prefer the const reference, as a habit mostly, unless what I'm
passing is a built-in type, in which case I pass by value. But that's just me.

-Howard

Jul 23 '05 #6
In article <d1**********@domitilla.aioe.org>,
"modemer" <me@privacy.net.invalid> wrote:
Howard,
I also wonder why the compiler allows you to declare two functions which
will later lead to an inability to pick the best match.


Good point! I think you clarified my question.


The compiler allows it because, if you don't use the function then it
doesn't matter that there would be a conflict.
Jul 23 '05 #7
Daniel T. wrote:
In article <d1**********@domitilla.aioe.org>,
"modemer" <me@privacy.net.invalid> wrote:

Howard,

I also wonder why the compiler allows you to declare two functions which
will later lead to an inability to pick the best match.


Good point! I think you clarified my question.

The compiler allows it because, if you don't use the function then it
doesn't matter that there would be a conflict.


And you can "use" that function without ambiguity. In particular, you
can assign its address to a pointer to member function with a suitable type.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 23 '05 #8
Ah, and the mystery is solved!

Here is code to illustrate what Pete is saying:

class MyClass
{
public:
MyClass() { cout << " Constructor!\n"; }
MyClass(const MyClass& i) { cout << " Copy
Constructor!\n"; }
virtual ~MyClass() { cout << " Destructor!\n"; }

};

void f(MyClass in) {cout<<" f(MyClass)\n";}
void f(const MyClass &in) {cout<<" f(const MyClass&)\n";}

typedef void (*f1p_t)(MyClass);
typedef void (*f2p_t)(const MyClass&);

int main()
{
MyClass a;

f1p_t f1p = f;
f2p_t f2p = f;

cout << " * About to call f(MyClass):\n";
f1p(a);
cout << " * About to call f(const MyClass&):\n";
f2p(a);
cout << "Done with calls; back in main\n";
}

Jul 23 '05 #9
Howard wrote:
I also wonder why the compiler allows you to declare two functions which
will later lead to an inability to pick the best match.
Because these functions can be used in other contexts, where the
compiler will not be faced with the problem of picking the best match.
Perhaps there is a
way to construct a call to one that will not appear to be a call to the
other?


Yes.

MyClass in;
void (*p)(MyClass) = &f;
(*p)(in);

The code above "forcefully" picks and calls the second version of the
function.

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #10
"modemer" <me@privacy.net.invalid> wrote:
If I define the following codes:

void f(const MyClass & in) {cout << "f(const)\n";}
void f(MyClass in) {cout<<"f()\n";}

MyClass myclass;
f(myclass);

Compiler complain that it can't find the best match. Anyone
could give a detail explanation in theory? Which one is good?


The same error also exists if myclass is declared const:
/////////////////////
void f(const MyClass & in) { cout << "f(const reference)\n"; }
void f(MyClass in) { cout << "f(value)\n"; }

const MyClass myclass;
f(myclass);
//
If "f(const reference)" is changed to "f(reference)", the error also
occurs!:
/////////////////////
void f(MyClass & in) { cout << "f(reference)\n"; }
void f(MyClass in) { cout << "f(value)\n"; }

MyClass myclass;
f(myclass);
//
However, the error does not occur -- and f(value) is called -- if myclass is
const:
/////////////////////
void f(MyClass & in) { cout << "f(reference)\n"; }
void f(MyClass in) { cout << "f(value)\n"; }

const MyClass myclass;
f(myclass);
//
The error will occur (twice) no-matter the constness of myclass if all three
functions are defined:
/////////////////////
void f(MyClass & in) { cout << "f(reference)\n"; }
void f(const MyClass & in) { cout << "f(const reference)\n"; }
void f(MyClass in) { cout << "f(value)\n"; }

const MyClass constmyclass;
MyClass myclass;
f(constmyclass);
f(myclass)
//
However, the compiler error doesn't exist if f(value) isn't defined:
/////////////////////
void f(MyClass & in) { cout << "f(reference)\n"; }
void f(const MyClass & in) { cout << "f(const reference)\n"; }

/*const*/ MyClass myclass;
f(myclass);
//

In the previous example though, when the program runs, f(reference) is
called if myclass is non-const and f(const reference) is called if myclass
is const.
The situations are exactly the same if "f(value)" is replaced with "f(const
value)". However, if both "f(value)" and "f(const value)" exist, the
compiler says that f(value) has already been defined (or "f(const value)",
depending on which is defined first).
Other responses in the thread indicate that it is possible to explicitly
specify which function to call. To me that seems like bending-over-backward
to deal with a possible shortcoming of the language and/or compiler.

Yes maybe the compiler should be able to handle the ambiguities better.
However, why differentiate functionality based only on switching the
non-const/const and/or value/reference nature of a function's parameter(s)?
(And if that is found to be useful, would it be called "ambiguous
polymorphishm"?)

crichmon
Jul 23 '05 #11

"crichmon" <cr******@gmail.com> wrote in message
news:7T*****************@newsread2.news.atl.earthl ink.net...
"modemer" <me@privacy.net.invalid> wrote:
If I define the following codes:

void f(const MyClass & in) {cout << "f(const)\n";}
void f(MyClass in) {cout<<"f()\n";}

MyClass myclass;
f(myclass);

Compiler complain that it can't find the best match. Anyone
could give a detail explanation in theory? Which one is good?
The same error also exists if myclass is declared const:
/////////////////////
void f(const MyClass & in) { cout << "f(const reference)\n"; }
void f(MyClass in) { cout << "f(value)\n"; }

const MyClass myclass;
f(myclass);
//
If "f(const reference)" is changed to "f(reference)", the error also
occurs!:
/////////////////////
void f(MyClass & in) { cout << "f(reference)\n"; }
void f(MyClass in) { cout << "f(value)\n"; }

MyClass myclass;
f(myclass);
//
However, the error does not occur -- and f(value) is called -- if myclass

is const:
/////////////////////
void f(MyClass & in) { cout << "f(reference)\n"; }
void f(MyClass in) { cout << "f(value)\n"; }

const MyClass myclass;
f(myclass);
//
The error will occur (twice) no-matter the constness of myclass if all three functions are defined:
/////////////////////
void f(MyClass & in) { cout << "f(reference)\n"; }
void f(const MyClass & in) { cout << "f(const reference)\n"; }
void f(MyClass in) { cout << "f(value)\n"; }

const MyClass constmyclass;
MyClass myclass;
f(constmyclass);
f(myclass)
//
However, the compiler error doesn't exist if f(value) isn't defined:
/////////////////////
void f(MyClass & in) { cout << "f(reference)\n"; }
void f(const MyClass & in) { cout << "f(const reference)\n"; }

/*const*/ MyClass myclass;
f(myclass);
//

In the previous example though, when the program runs, f(reference) is
called if myclass is non-const and f(const reference) is called if myclass
is const.
The situations are exactly the same if "f(value)" is replaced with "f(const value)". However, if both "f(value)" and "f(const value)" exist, the
compiler says that f(value) has already been defined (or "f(const value)",
depending on which is defined first).
Other responses in the thread indicate that it is possible to explicitly
specify which function to call. To me that seems like bending-over-backward to deal with a possible shortcoming of the language and/or compiler.

Yes maybe the compiler should be able to handle the ambiguities better.
However, why differentiate functionality based only on switching the
non-const/const and/or value/reference nature of a function's parameter(s)? (And if that is found to be useful, would it be called "ambiguous
polymorphishm"?)

crichmon


Thanks crichmon's analysis in such depth, so far looks like nobody has ever
found any C++ works analyzing "ambiguous" in detail and found the reason why
C++ allows these "ambiguous" existing, rather than just like trying to
cover all of type checking.
Jul 23 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
1885
by: learning_C++ | last post by:
Hi, I compiled some code. In the function friend ostream& operator<<(ostream& os, const complex c); I use the later argument complex c and complex& c. I can get the same values and there is no...
5
1613
by: modemer | last post by:
I saw someone use the following code: void func(MyClass *& myCls) { myCls->test(); } // call func(): func(new MyClass);
5
1491
by: Gunnar G | last post by:
What is the difference between the two lines in the main function? class MyClass{ ....}; int main(){ MyClass a(); MyClass a; }
15
1820
by: Bart | last post by:
Hi, I receive an utf8 character from a database, like 田 (Japanese Character, style: &#XXXXX). How can I visualize the Japanese character on my application? I have found the class...
1
2577
by: Iced Crow | last post by:
What is the difference between using MyClass and Me inside of inherited classes?
9
1961
by: Anoj | last post by:
Hi All, is there any performance difference between + and & operator while concating string litrels. which one is better and why?? Thanx
3
2089
by: OgaW | last post by:
Hey anybody, What the difference between RDRAM and DDRAM? Is the RDRAM going to phrase out in the current market? Any difference between a memory speed and a CPU pentium speed? Urgently...
4
1819
by: nembo kid | last post by:
Was wondering why the function that overloads = operator, returns always a const reference to the class. Why the qualifier 'const'? Thanks in advance
2
4101
by: qwedster | last post by:
Folks! What is the difference between PostBack and Callback ( !IsPostBack and if(!IsCallback)) Like in the following Code Snippet: protected void Page_Load(object sender, EventArgs...
0
7137
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7347
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7416
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7073
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7506
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5656
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5062
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3218
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
443
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.