473,385 Members | 1,834 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Why doesn't this compile....?

I've got a base class foo:

class foo {
....
};
And a derived class foo_d:

class foo_d : public foo {
};
I then make another class which takes a foo
in the constructor:

class bar {
public:
bar(foo&);
};
All easy stuff... but when I try this the compiler
complains:

bar b(foo_d());

OTOH this is ok:

foo_d f;
bar b(f);

Why...?

--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again. They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful. But it happens
every day. I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address

Aug 6 '06 #1
14 1871
fungus <um*****@SOCKSartlum.comwrote:
class foo {
...
};
class foo_d : public foo {
};
class bar {
public:
bar(foo&);
};
complains:

bar b(foo_d());

OTOH this is ok:

foo_d f;
bar b(f);

Why...?
In the first case, you create a temporary 'foo_d' object and want to
pass this to the ctor of 'bar'. The problem is, that temporaries can
only be bound to _const_ references. But the 'bar' ctor takes a
non-const reference. In the second case you do not have this problem,
because there is no temporary.

You can fix this by changing the constructor of 'bar' to take a
'foo_d const&'.
hth
--
jb

(reply address in rot13, unscramble first)
Aug 6 '06 #2
fungus wrote:
>

All easy stuff... but when I try this the compiler
complains:

bar b(foo_d());

OTOH this is ok:

foo_d f;
bar b(f);

Why...?
You can't bind rvalues to non-const references.
Make the constructor
bar(const foo&);
Aug 6 '06 #3
Jakob Bieling wrote:
>
>....complains:

bar b(foo_d());

OTOH this is ok:

foo_d f;
bar b(f);

Why...?

You can fix this by changing the constructor of 'bar' to take a
'foo_d const&'.
I thought of that.... but when I try it I get a
different error:

test.cpp: error: ‘foo::foo(const foo&)’ is private
In constructor ‘bar::bar()’
warning: synthesized method ‘foo_d::foo_d(const foo_d&)’
first required here
(and yes, foo::foo(const foo&) is declared private...)
--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again. They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful. But it happens
every day. I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address

Aug 6 '06 #4
fungus wrote:
>
(and yes, foo::foo(const foo&) is declared private...)

It must be public to use it from outside the class.

Aug 6 '06 #5
Ron Natalie wrote:
fungus wrote:
>>
(and yes, foo::foo(const foo&) is declared private...)

It must be public to use it from outside the class.
It's private for a reason...

The point is that the copy constructor
shouldn't even be called...I'm passing
a reference!

--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again. They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful. But it happens
every day. I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address

Aug 6 '06 #6
* fungus:
Ron Natalie wrote:
>fungus wrote:
>>>
(and yes, foo::foo(const foo&) is declared private...)

It must be public to use it from outside the class.

It's private for a reason...

The point is that the copy constructor
shouldn't even be called...I'm passing
a reference!
When passing a temporary to 'T const&' argument, the copy constructor
must be available, and it can be (but usually isn't) called.

One workaround is to provide a conversion to 'T const&'.

AFAIK nobody has come up with any reason why that could be undesirable,
but OTOH, AFAIK nobody actually uses this technique, so I make no
recommendation.

--
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?
Aug 6 '06 #7
Alf P. Steinbach wrote:
* fungus:
>Ron Natalie wrote:
>>fungus wrote:
(and yes, foo::foo(const foo&) is declared private...)
It must be public to use it from outside the class.

It's private for a reason...

The point is that the copy constructor
shouldn't even be called...I'm passing
a reference!

When passing a temporary to 'T const&' argument, the copy constructor
must be available, and it can be (but usually isn't) called.

One workaround is to provide a conversion to 'T const&'.

AFAIK nobody has come up with any reason why that could be undesirable,
but OTOH, AFAIK nobody actually uses this technique, so I make no
recommendation.
Are you sure about the conversion function?

12.3.2/1:
... A conversion function is never used to convert a (possibly
cv-qualified) object to the (possibly cv-qualified) same object type (or a
reference to it), to a (possibly cv-qualified) base class of that type (or
a reference to it), or to (possibly cv-qualified) void.103)

103) Even though never directly called to perform a conversion, such
conversion functions can be declared and can potentially be reached
through a call to a virtual conversion function in a base class.
Or did you mean just an ordinary member like:

foo const & self ( void ) const {
return ( *this );
}

Best

Kai-Uwe Bux
Aug 6 '06 #8
* Kai-Uwe Bux:
Alf P. Steinbach wrote:
>* fungus:
>>Ron Natalie wrote:
fungus wrote:

(and yes, foo::foo(const foo&) is declared private...)
>
>
It must be public to use it from outside the class.

It's private for a reason...

The point is that the copy constructor
shouldn't even be called...I'm passing
a reference!
When passing a temporary to 'T const&' argument, the copy constructor
must be available, and it can be (but usually isn't) called.

One workaround is to provide a conversion to 'T const&'.

AFAIK nobody has come up with any reason why that could be undesirable,
but OTOH, AFAIK nobody actually uses this technique, so I make no
recommendation.

Are you sure about the [implicit] conversion function?
No, I was not sure about the implicit variant, I thought that was what I
wrote... ;-)

It was discussed in clc++m in connection with boost::noncopyable (or
whatever that class is called).

But as I recall nobody came up with:
12.3.2/1:
... A conversion function is never used to convert a (possibly
cv-qualified) object to the (possibly cv-qualified) same object type (or a
reference to it), to a (possibly cv-qualified) base class of that type (or
a reference to it), or to (possibly cv-qualified) void.103)

103) Even though never directly called to perform a conversion, such
conversion functions can be declared and can potentially be reached
through a call to a virtual conversion function in a base class.

Or did you mean just an ordinary member like:

foo const & self ( void ) const {
return ( *this );
}
I think that's the best solution, although I'd call it 'ref', and leave
out the C style void argument spec. :-)

Checking how compilers treat the /implicit/ conversion operator, MSVC
7.1 ignores it and the lack of accessible copy constructor, because
already C++0x compliant (heh! -- it's just a bug that happens to
coincide with anticipated change of the standard); g++ 3.4.4 invokes the
operator; and Comeau Online 4.3.3 produces first a warning that it will
never be used, and then an error on the attempted usage.

--
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?
Aug 6 '06 #9
fungus wrote:
Jakob Bieling wrote:
>>fungus wrote:
>>>
bar b(foo_d());
This code declares a function 'b', returning 'bar' and taking
one argument: a pointer to function taking no arguments and
returning 'foo_d'.

It doesn't declare an object.

This code by itself won't generate an error, but you will get
errors if you then try and use 'b' as if it were an object.

You could avoid this problem by writing:
bar b((foo_d()));

(there are other workarounds available too).
You can fix this by changing the constructor of 'bar' to take a
'foo_d const&'.

I thought of that.... but when I try it I get a
different error:

test.cpp: error: 'foo::foo(const foo&)' is private
In constructor 'bar::bar()'
warning: synthesized method 'foo_d::foo_d(const foo_d&)'
first required here
(and yes, foo::foo(const foo&) is declared private...)
You must have some code you didn't show us (at a guess,
does foo_d actually have a parameter to the constructor?)

If you did in fact write:
bar b((foo_d()));
or
bar b(foo_d(3)); // with appropriate foo_d constructor

you would get this error.

In this case, the error is because in order to bind a temporary
object to a reference to const, the temporary object must have
a publicly accessible copy-constructor.
>>>
OTOH this is ok:

foo_d f;
bar b(f);
That code should work, without the need for a public
copy constructor. What error does it give you?

Aug 7 '06 #10
Alf P. Steinbach wrote:
>
When passing a temporary to 'T const&' argument, the copy constructor
must be available, and it can be (but usually isn't) called.
That seems unnecessary to me...
One workaround is to provide a conversion to 'T const&'.
I can live with writing the code in two lines
I was just curious why it didn't work.
AFAIK nobody has come up with any reason why that could be undesirable,
but OTOH, AFAIK nobody actually uses this technique, so I make no
recommendation.
I used it!

I'm currently porting a program from VC++ to G++
and it broke some code. My base class foo had an
operator bool() defined and the compiler was calling
the wrong constructor when it created the "bar"
(bar also has an integer constructor).
--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again. They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful. But it happens
every day. I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address

Aug 7 '06 #11
fungus wrote:
>
I'm currently porting a program from VC++ to G++
and it broke some code. My base class foo had an
operator bool() defined and the compiler was calling
the wrong constructor when it created the "bar"
(bar also has an integer constructor).
Get rid of it before it turns round and bites you.

--
Ian Collins.
Aug 7 '06 #12
Ian Collins wrote:
My base class foo had an
>operator bool() defined and the compiler was
calling the wrong constructor (bar also has
an integer constructor).
Get rid of it before it turns round and bites you.
I did. I've recently come to the conclusion
that "operator bool()" is a bug waiting to
happen. I now do "bool ok() const;"

--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.

In science it often happens that scientists say, 'You know
that's a really good argument; my position is mistaken,'
and then they actually change their minds and you never
hear that old view from them again. They really do it.
It doesn't happen as often as it should, because scientists
are human and change is sometimes painful. But it happens
every day. I cannot recall the last time something like
that happened in politics or religion.

- Carl Sagan, 1987 CSICOP keynote address

Aug 7 '06 #13
fungus wrote:
Ian Collins wrote:
> My base class foo had an
>>operator bool() defined and the compiler was
>>calling the wrong constructor (bar also has
an integer constructor).
>>>
Get rid of it before it turns round and bites you.

I did. I've recently come to the conclusion
that "operator bool()" is a bug waiting to
happen. I now do "bool ok() const;"
Good. This should be embossed in the biggest font that will fit on the
first page of all C++ books.

--
Ian Collins.
Aug 7 '06 #14
ssb

My guess is because the function expects a reference to an object, and
you are actually passing an object, not a reference. The function
strictly expects a reference to foo.

OTOH, the second trial is correct, because you ARE passing a reference
to an object.

Aug 8 '06 #15

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

Similar topics

0
by: James Thurley | last post by:
I'm trying to dynamically compile assemblies and cache them to disk, which seems to work fine. When the data I'm compiling from changes, I want to re-generate the assembly and use the new version....
4
by: Fernando Cuenca | last post by:
Hi, I'm trying to explicitly instantiate a template function using the following syntax: obj.template_func<type>(params); It compiles OK when used from a regular function, but it doesn't...
12
by: Rhino | last post by:
I am having an odd problem: the sqlj command on my system doesn't work. I am running DB2 (LUW) V8 (FP8) on WinXP. I haven't done an sqlj program since Version 6 of DB2 (LUW) so I checked the...
3
by: Karl Irvin | last post by:
When I click Debug>Compile, my modules seem to comple OK but the Compile menu choice doesn't gray out (to indicate compiling is not needed). The IsCompiles returns false, no matter how many times...
149
by: Christopher Benson-Manica | last post by:
(Followups set to comp.std.c. Apologies if the crosspost is unwelcome.) strchr() is to strrchr() as strstr() is to strrstr(), but strrstr() isn't part of the standard. Why not? --...
1
by: rvan | last post by:
Hi, I am trying to port one of my older MFC APP created in VC 6.0 to VC 7.0. Right away after starting the compile process, I get following errors and compilation stops. "d:\Microsoft .NET...
4
by: Eric Lilja | last post by:
Is this an invalid program? Doesn't compile on my system: #include <cstdio> class Why { enum TArch {LITTLE_ENDIAN, BIG_ENDIAN, NON_IEEE}; TArch Architecture; }; int
10
by: Sourcerer | last post by:
I wrote this very simple code in .NET VC++. I compiled it on my system, and tried to run it on my friend's computer (he doesn't have the compiler). We both have Windows XP Professional. I have .NET...
13
by: hn.ft.pris | last post by:
Hi: I have the following simple program: #include<iostream> using namespace std; int main(int argc, char* argv){ const double L = 1.234; const int T = static_cast<const int>(L); int arr;
35
by: mwelsh1118 | last post by:
Why doesn't C# allow incremental compilation like Java? Specifically, in Java I can compile single .java files in isolation. The resulting individual .class files can be grouped into .jar files....
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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
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...

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.