avoid implicit cctor call

O

Olaf

Hi,

here the following test code

#include <iostream>

using namespace std;

struct Foo {
Foo() { cout << " Foo()\n"; }
~Foo() { cout << "~Foo()\n"; }
void set() const { cout << "Foo::set()\n"; }
};

struct Bar {
void set(const Foo& foo) const { foo.set(); }
};

int main() {
Bar b;
b.set( Foo() );
}

shows:

Foo()
Foo()
Foo::set()
~Foo()
~Foo()

Well, obviously the copy ctor from temporary is called. Can I avoid this
by using a different way?
Background: Foo can contain strings (should not be the problem) but also
function pointers and lists. About the last, I'm not sure about the copy
semantic. Any help here?

Thanks,
Olaf
 
V

Victor Bazarov

Olaf said:
here the following test code

#include <iostream>

using namespace std;

struct Foo {
Foo() { cout << " Foo()\n"; }
~Foo() { cout << "~Foo()\n"; }
void set() const { cout << "Foo::set()\n"; }
};

struct Bar {
void set(const Foo& foo) const { foo.set(); }
};

int main() {
Bar b;
b.set( Foo() );
}

shows:

Foo()
Foo()
Foo::set()
~Foo()
~Foo()

Well, obviously the copy ctor from temporary is called. Can I avoid
this by using a different way?

If you want to use a temporary, no, there is no other way. If you
could have a separate variable of type 'Foo', you could pass by non-
const refefence (Foo&), if you promise not to call any non-const
functions, or just a pointer to const Foo - that guarantees no copying.

The language definition says that a copy can be made during binding
of a reference to a temporary. It does not have to be, but it can.
Background: Foo can contain strings (should not be the problem) but
also function pointers and lists. About the last, I'm not sure about
the copy semantic. Any help here?

If you mean 'std::list', its copy semantics are well defined, but
copying collections is expensive, so you should probably try to avoid
those.

V
 
T

terminator

Hi,

here the following test code

#include <iostream>

using namespace std;

struct Foo {
Foo() { cout << " Foo()\n"; }
~Foo() { cout << "~Foo()\n"; }
void set() const { cout << "Foo::set()\n"; }

};

struct Bar {
void set(const Foo& foo) const { foo.set(); }

};

int main() {
Bar b;
b.set( Foo() );

}

shows:

Foo()
Foo()
Foo::set()
~Foo()
~Foo()

Well, obviously the copy ctor from temporary is called. Can I avoid this
by using a different way?

*This is obviously wrong. Since you have not prepared a copy-ctor,any
copy construction would be silent(no-output).*
struct Bar {
void set(const Foo& foo) const { foo.set(); }
};

As 'Bar::set' accepts a reference - not a value - as its parameter no
copy-construction is invoked.I guess this output does not belong to
this code.You must have declared a 'Foo' object in your original code
which I guess is omited here because:
shows:

Foo()
Foo()
Foo::set()
~Foo()
~Foo()

this means twice default-construction and twice destruction.

Bar b;
b.set( Foo() );

Is 'Bar' derived form 'Foo'? This could also lead to the above output
as a result of default-construction of 'b'.

regards,
FM.
 
O

Olaf

terminator said:
*This is obviously wrong. Since you have not prepared a copy-ctor,any
copy construction would be silent(no-output).*

Yes, you are right. I did verify the snippet again. No idea what I did
before (probably for test purpose there was a Foo created on stack).
Sorry for confusion.

Anyway, here a more real problem of me:

#include <iostream>
#include <boost/utility.hpp>

using namespace std;

struct Foo : public boost::noncopyable {
Foo() { cout << " Foo()\n"; }
~Foo() { cout << "~Foo()\n"; }
//Foo( const Foo& ) { cout << " Foo(const Foo&)\n"; }
void set() const { cout << "Foo::set()\n"; }
};

struct Bar {
void set(const Foo& foo) const { foo.set(); }
};

int main()
{
Bar b;

b.set( Foo() );
}

$ LANG=en g++ cctor.cpp -o cctor && ./cctor
/usr/include/boost/noncopyable.hpp: In copy constructor 'Foo::Foo(const
Foo&)':
/usr/include/boost/noncopyable.hpp:27: error:
'boost::noncopyable_::noncopyable::noncopyable(const
boost::noncopyable_::noncopyable&)' is private
cctor.cpp:6: error: within this context
cctor.cpp: In function 'int main()':
cctor.cpp:21: note: synthesized method 'Foo::Foo(const Foo&)' first
required here

Background more precise: Foo can have std::list<T> and function pointer
private data.

I can verify where the copy ctor is involved. Using the own (out
commented) Foo(const Foo&) did compile and run fine, but I'm not shure
about side effects here.

Thanks,
Olaf
 
V

Victor Bazarov

Olaf said:
[..] here a more real problem of me:

#include <iostream>
#include <boost/utility.hpp>

using namespace std;

struct Foo : public boost::noncopyable {
Foo() { cout << " Foo()\n"; }
~Foo() { cout << "~Foo()\n"; }
//Foo( const Foo& ) { cout << " Foo(const Foo&)\n"; }
void set() const { cout << "Foo::set()\n"; }
};

struct Bar {
void set(const Foo& foo) const { foo.set(); }
};

int main()
{
Bar b;

b.set( Foo() );

Binding of a reference to a temporary *requires* the type to be
copy-constructible. You basically want to have your cake and eat
it too. Can't happen. Either make it copy-constructible, or
don't expect to be able to bind a const reference to a temporary.
}

$ LANG=en g++ cctor.cpp -o cctor && ./cctor
/usr/include/boost/noncopyable.hpp: In copy constructor
'Foo::Foo(const Foo&)':
/usr/include/boost/noncopyable.hpp:27: error:
'boost::noncopyable_::noncopyable::noncopyable(const
boost::noncopyable_::noncopyable&)' is private
cctor.cpp:6: error: within this context
cctor.cpp: In function 'int main()':
cctor.cpp:21: note: synthesized method 'Foo::Foo(const Foo&)' first
required here

Background more precise: Foo can have std::list<T> and function
pointer private data.

I can verify where the copy ctor is involved. Using the own (out
commented) Foo(const Foo&) did compile and run fine, but I'm not shure
about side effects here.

Side effects of what?

V
 
O

Olaf

Background more precise: Foo can have std::list said:
Side effects of what?

The legacy C code get function pointers, allocated memory regions ...
Maybe these will be affected.

Thanks,
Olaf
 
T

terminator

Binding of a reference to a temporary *requires* the type to be
copy-constructible. You basically want to have your cake and eat
it too. Can't happen. Either make it copy-constructible, or
don't expect to be able to bind a const reference to a temporary.

what is the catch from such a restiriction?

regards,
FM.
 
V

Victor Bazarov

terminator said:
what is the benefit?

The benefit? I am not sure how to answer you. What is the benefit
from the limitation that to convert a pointer to a derived class to
a pointer to a base class you have to have the base class accessible?
Or, what's the benefit from the limitation that to convert void* to
a pointer to object one needs a 'static_cast'? Those limitations
often exist because without them it would be difficult to implement
a compiler, or other rules would be too complicated. What's the
benefit of limiting (from below) the age at which people can start
driving cars or vote? Avoiding chaos, avoiding having to prosecute
minors for a vehicular manslaughter.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top