472,989 Members | 2,987 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,989 software developers and data experts.

Conversion: via constructor or operator

Hi,

I have a question regarding the conversion of objects. When is the
conversion done by the constructor and when by the operator. My feeling
tells me that the constructor is preferred. But I couldn't find the
exact rule in the C++ standard.

And what if the classes have template parameters?

It would be great if somebody could get me a rough hint where in the
standard I should start reading.

I know that it is dangerous to have both a conversion constructor and a
conversion operator. But I want to learn more about this whole
mechanism.

Thanks,
Michael

//---------------------------------------
struct A;

struct B
{
B(const A &a);
};

struct A
{
operator B() const {}
};

B::B(const A &a) {}

int
main()
{
A a;
B b = a; // Uses always the constructor of B if possible?
return 0;
}
//----------------------------------------
Oct 30 '05 #1
7 3208
* Michael Lehn:
Hi,

I have a question regarding the conversion of objects. When is the
conversion done by the constructor and when by the operator. My feeling
tells me that the constructor is preferred.
If you mean, should you implement a conversion by providing a
constructor, or by providing an operator, then sometimes that is
clearcut, and sometimes it's personal preference.

If you mean, can one be called preferentially if both are defined, then
no, not in a conforming implementation.

A conforming compiler will reject such code.

But I couldn't find the exact rule in the C++ standard.

And what if the classes have template parameters?

It would be great if somebody could get me a rough hint where in the
standard I should start reading.

I know that it is dangerous to have both a conversion constructor and a
conversion operator. But I want to learn more about this whole
mechanism.
It's not dangerous: it's just not allowed.

//---------------------------------------
struct A;

struct B
{
B(const A &a);
};

struct A
{
operator B() const {}
};

B::B(const A &a) {}

int
main()
{
A a;
B b = a; // Uses always the constructor of B if possible?
return 0;
}
//----------------------------------------


MSVC 7.1 incorrectly compiles this. g++ 3.4.4 rejects it, correctly.
Comeau 4.3.3 (huh, what's with those numbers?) rejects it, correctly.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Oct 30 '05 #2
Alf P. Steinbach wrote:
* Michael Lehn:
Hi,

I have a question regarding the conversion of objects. When is the
conversion done by the constructor and when by the operator. My feeling
tells me that the constructor is preferred.


If you mean, should you implement a conversion by providing a
constructor, or by providing an operator, then sometimes that is
clearcut, and sometimes it's personal preference.

If you mean, can one be called preferentially if both are defined, then
no, not in a conforming implementation.

A conforming compiler will reject such code.

But I couldn't find the exact rule in the C++ standard.

And what if the classes have template parameters?

It would be great if somebody could get me a rough hint where in the
standard I should start reading.

I know that it is dangerous to have both a conversion constructor and a
conversion operator. But I want to learn more about this whole
mechanism.


It's not dangerous: it's just not allowed.

//---------------------------------------
struct A;

struct B
{
B(const A &a);
};

struct A
{
operator B() const {}
};

B::B(const A &a) {}

int
main()
{
A a;
B b = a; // Uses always the constructor of B if possible?
return 0;
}
//----------------------------------------


MSVC 7.1 incorrectly compiles this. g++ 3.4.4 rejects it, correctly.
Comeau 4.3.3 (huh, what's with those numbers?) rejects it, correctly.


But gcc 4.0 does compile this program which suggests that gcc 3.4.4's
failure to compile this program was an error. And a close reading of
the Standard certainly provides no reason why there should be an error
in this case. There is only one user-defined conversion that could
match B b = a, and it is not the one selected by the overload
resolution as the best match anyway.

Since B's constructor accepts a const A& parameter, the variable, a,
used to initialize b in

B b = a;

is an "exact match" for the type needed to construct a B object
directly. No conversion takes place: a is passed to B's constructor, as
is. If that were not the case, and the initializer, a, had to be
converted to some other type in order to match the type of parameter
declared in B's constructor, then there would exist two user-defined
conversions that could be invoked to construct b. And if one of those
conversion sequences were to be selected as the best match then at that
point an ambiguous conversion error would be reported.

Greg

Oct 31 '05 #3
* Greg:
Alf P. Steinbach wrote:
* Michael Lehn:
Hi,

I have a question regarding the conversion of objects. When is the
conversion done by the constructor and when by the operator. My feeling
tells me that the constructor is preferred.
If you mean, should you implement a conversion by providing a
constructor, or by providing an operator, then sometimes that is
clearcut, and sometimes it's personal preference.

If you mean, can one be called preferentially if both are defined, then
no, not in a conforming implementation.

A conforming compiler will reject such code.

But I couldn't find the exact rule in the C++ standard.

And what if the classes have template parameters?

It would be great if somebody could get me a rough hint where in the
standard I should start reading.

I know that it is dangerous to have both a conversion constructor and a
conversion operator. But I want to learn more about this whole
mechanism.


It's not dangerous: it's just not allowed.

//---------------------------------------
struct A;

struct B
{
B(const A &a);
};

struct A
{
operator B() const {}
};

B::B(const A &a) {}

int
main()
{
A a;
B b = a; // Uses always the constructor of B if possible?
return 0;
}
//----------------------------------------


MSVC 7.1 incorrectly compiles this. g++ 3.4.4 rejects it, correctly.
Comeau 4.3.3 (huh, what's with those numbers?) rejects it, correctly.


But gcc 4.0 does compile this program which suggests that gcc 3.4.4's
failure to compile this program was an error. And a close reading of
the Standard certainly provides no reason why there should be an error
in this case.


You need to read even closer...

There is only one user-defined conversion that could
match B b = a, and it is not the one selected by the overload
resolution as the best match anyway.

Since B's constructor accepts a const A& parameter, the variable, a,
used to initialize b in

B b = a;

is an "exact match" for the type needed to construct a B object
directly.
The B object is not constructed directly except after optimization, and
that _possible_ optimization does not affect which rules are in play;
formally 'b' is here copy-constructed from a B object.

It would be different if the OP had used direct initialization (the C++
initialization syntax).

Then you'd have an exact match.

No conversion takes place: a is passed to B's constructor, as
is. If that were not the case, and the initializer, a, had to be
converted to some other type in order to match the type of parameter
declared in B's constructor, then there would exist two user-defined
conversions that could be invoked to construct b.
Yes, that's the situation here. 'a' must be converted to a B, which is
then passed to B's copy constructor. There are two ways to convert 'a'
to a B in a single step, hence the conversion is ambigious.

And if one of those
conversion sequences were to be selected as the best match then at that
point an ambiguous conversion error would be reported.


That's what a conforming compiler such as Comeau does.
PS: It would be nice if you could report the bug in g++ 4.0!

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Oct 31 '05 #4
Alf P. Steinbach wrote:
And if one of those
conversion sequences were to be selected as the best match then at that
point an ambiguous conversion error would be reported.


That's what a conforming compiler such as Comeau does.


struct A;
struct B { B() {} B(const A &a) {} };
struct A { operator B() const { return B(); } };

int main()
{
A a;
B b = a;
}

Strange, Comeau 4.3.3 actually compiles this code fine. It does not
compile the original code, but this is only because the body of
"operator B() const" is empty, which is a completely different error.

--

Valentin Samko - http://www.valentinsamko.com

Oct 31 '05 #5
* Valentin.Samko:
Alf P. Steinbach wrote:
And if one of those
conversion sequences were to be selected as the best match then at that
point an ambiguous conversion error would be reported.
That's what a conforming compiler such as Comeau does.


struct A;
struct B { B() {} B(const A &a) {} };
struct A { operator B() const { return B(); } };

int main()
{
A a;
B b = a;
}

Strange, Comeau 4.3.3 actually compiles this code fine.


Sorry, you're wrong.

Comeau 4.3.3 does not compile your code, even in non-strict mode.

You can try it out at <url: http://www.comeaucomputing.com/tryitout/>.

Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:non-strict warnings C++

"ComeauTest.c", line 8: error: more than one user-defined conversion
from "A" to "B"
applies:
function "A::operator B() const"
function "B::B(const A &)"
B b = a;
^

1 error detected in the compilation of "ComeauTest.c".

It does not
compile the original code, but this is only because the body of
"operator B() const" is empty, which is a completely different error.


Sorry, you're wrong.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Oct 31 '05 #6
Alf P. Steinbach wrote:
Strange, Comeau 4.3.3 actually compiles this code fine. Sorry, you're wrong.

It compiles this code fine using vc++7.1 as a backend, without --strict.
Why would I write this if it didn't compile the code for me?
Comeau 4.3.3 does not compile your code, even in non-strict mode. It does, using vc7.1 as a backend.
You can try it out at <url: http://www.comeaucomputing.com/tryitout/>. I just used my copy.
como --vc71 0.cpp como: Warning: COMO_MS_INCLUDE environment variable missing
Comeau C/C++ 4.3.3 (Jan 13 2004 11:29:09) for MS_WINDOWS_x86
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:non-strict warnings microsoft C++aout

It does not
compile the original code, but this is only because the body of
"operator B() const" is empty, which is a completely different error.

Sorry, you're wrong.

Again, this depends on the backend compiler and options. I am quite right according to my
copy of comeau, using default options.

--

Valentin Samko - http://www.valentinsamko.com
Oct 31 '05 #7
* Valentin Samko:
Alf P. Steinbach wrote:
Strange, Comeau 4.3.3 actually compiles this code fine.

Sorry, you're wrong.

It compiles this code fine using vc++7.1 as a backend, without --strict.
Why would I write this if it didn't compile the code for me?
Comeau 4.3.3 does not compile your code, even in non-strict mode.

It does, using vc7.1 as a backend.


Grumble.

Anyway, the code's formally incorrect.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Oct 31 '05 #8

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

Similar topics

9
by: Tanmoy Bhattacharya | last post by:
Hi, This is a question about whether I am right that a particular syntactic sugar is missing in C++. Let me explain with an example. Let us say I have a class for complex numbers, and I want...
4
by: Master of C++ | last post by:
Hi, This is a simple question. In the following example, .. class Vector .. { .. private: .. int *Numbers; .. int vLength; ..
5
by: Vijai Kalyan | last post by:
Hello, I have come back to C++ after a couple of years with Java so I am quite rusty and this question may seem poor: My platform is Windows XP with MSVC 7.1. I have a class with a...
3
by: Alexander Stippler | last post by:
Given the following code snippet we get some unexpected behaviour: //-------------------------------------------------------------------- #include <iostream> using namespace std; struct A {...
3
by: Steve Richter | last post by:
here is a warning I am getting in a C++ .NET compile: c:\SrNet\jury\JuryTest.cpp(55) : warning C4927: illegal conversion; more than one user-defined conversion has been implicitly applied while...
6
by: Dhirendra Singh | last post by:
Hi, The following C++ program is not compiling on my system. #include <iostream> using namespace std; class complex { double re, im; public: complex( ) :re(0), im(0) {}
2
by: =?Utf-8?B?U2FtZWVrc2hh?= | last post by:
Suppose there are 2 classes A and B with a int parameter called 'val' in each. Both of them provide a public constructor with int type parameter. Suppose class A provides a explicit conversion...
5
by: vairavans | last post by:
Hi Everyone, I have the following code, class B { }; class A {
6
by: Rahul | last post by:
Hi Everyone, I have the following code, class B; class A { public : operator B();
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
4
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

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.