Topic: private copy constructor and reference args
Author: John Salmon <jsalmon@thesalmons.org>
Date: Sat, 11 Aug 2007 20:47:35 CST Raw View
I've got a class with a private copy constructor
that I'd like to pass as a reference argument to a
function.
Gcc is unhappy with the following code unless I create an explicit
temporary. Comeau's online compiler seems to think it's fine. It
looks OK to me, too. Since the argument to func() is a reference to
Foo, there's no need for the compiler to copy-construct a temporary.
Or is there? Is gcc correct to complain? Or is comeau correct to
accept this?
<snip>
class Foo {
Foo(const Foo& f);
public:
Foo() {}
};
void
func( const Foo& foo){
}
int
main(int argc, char **argv){
#ifndef EXPLICIT_TEMPORARY
func(Foo());
#else
Foo f;
func(f);
#endif
return 0;
}
</snip>
Gcc (4.1.1) says:
[jsalmon@river junk]$ gcc noncopyable.cpp
noncopyable.cpp: In function 'int main(int, char**)':
noncopyable.cpp:2: error: 'Foo::Foo(const Foo&)' is private
noncopyable.cpp:14: error: within this context
[jsalmon@river junk]$ gcc -DEXPLICIT_TEMPORARY noncopyable.cpp
[jsalmon@river junk]$ a.out
[jsalmon@river junk]$
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Siddharth Jain <siddharthjain.in@gmail.com>
Date: Sun, 12 Aug 2007 10:15:17 CST Raw View
On Aug 12, 7:47 am, John Salmon <jsal...@thesalmons.org> wrote:
> <snip>
> class Foo {
> Foo(const Foo& f);
> public:
> Foo() {}
>
> };
>
> void
> func( const Foo& foo){
>
> }
>
> int
> main(int argc, char **argv){
> #ifndef EXPLICIT_TEMPORARY
> func(Foo());
> #else
> Foo f;
> func(f);
> #endif
> return 0;}
>
> </snip>
>
> Gcc (4.1.1) says:
>
> [jsalmon@river junk]$ gcc noncopyable.cpp
> noncopyable.cpp: In function 'int main(int, char**)':
> noncopyable.cpp:2: error: 'Foo::Foo(const Foo&)' is private
> noncopyable.cpp:14: error: within this context
> [jsalmon@river junk]$ gcc -DEXPLICIT_TEMPORARY noncopyable.cpp
> [jsalmon@river junk]$ a.out
> [jsalmon@river junk]$
TC++PL page no 98 says that:
In case of initializer for a const T& :
1 first, implicit type conversion to T is applied if necessary.
2. then, the resulting value is placed in a temporary variable of type
T; and
3. finally, this temporary variable is used as the value of the
initializer.
(eg in case of : const double& cdr=1;
it is actually
double tmp = double(1);
const double& cdr = tmp;
creating this temporary would require a public copy constructor, that
is why gcc is asking for a copy constructor when explicit temporary is
not used.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: john.salmon@gmail.com
Date: Sun, 12 Aug 2007 13:14:22 CST Raw View
On Aug 12, 12:15 pm, Siddharth Jain <siddharthjain...@gmail.com>
wrote:
> On Aug 12, 7:47 am, John Salmon <jsal...@thesalmons.org> wrote:
>
>
>
> > <snip>
> > class Foo {
> > Foo(const Foo& f);
> > public:
> > Foo() {}
>
> > };
>
> > void
> > func( const Foo& foo){
>
> > }
>
> > int
> > main(int argc, char **argv){
> > #ifndef EXPLICIT_TEMPORARY
> > func(Foo());
> > #else
> > Foo f;
> > func(f);
> > #endif
> > return 0;}
>
> > </snip>
>
> > Gcc (4.1.1) says:
>
> > [jsalmon@river junk]$ gcc noncopyable.cpp
> > noncopyable.cpp: In function 'int main(int, char**)':
> > noncopyable.cpp:2: error: 'Foo::Foo(const Foo&)' is private
> > noncopyable.cpp:14: error: within this context
> > [jsalmon@river junk]$ gcc -DEXPLICIT_TEMPORARY noncopyable.cpp
> > [jsalmon@river junk]$ a.out
> > [jsalmon@river junk]$
>
> TC++PL page no 98 says that:
> In case of initializer for a const T& :
> 1 first, implicit type conversion to T is applied if necessary.
> 2. then, the resulting value is placed in a temporary variable of type
> T; and
> 3. finally, this temporary variable is used as the value of the
> initializer.
>
> (eg in case of : const double& cdr=1;
> it is actually
> double tmp = double(1);
> const double& cdr = tmp;
>
> creating this temporary would require a public copy constructor, that
> is why gcc is asking for a copy constructor when explicit temporary is
> not used.
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html ]
You're right to observe that the problem is related to const reference
initialization.
The function call is unnecessary baggage.
Also, it seems that Comeau complains if I turn off C++0x extensions.
But I am still confused. In the following code, how is the
initialization of g
different from the initialization of h, and what changes in C++0x to
make the
initialization of h acceptable?
class Foo {
Foo(const Foo& f);
public:
Foo(){}
};
int
main(int argc, char **argv){
Foo f; // ok, default ctor
const Foo &g(f); // ok
const Foo &h((Foo())); // fails g++, Comeau without C++0x
extensions
return &g!=&h;
}
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Sun, 12 Aug 2007 13:34:51 CST Raw View
On Aug 12, 4:47 am, John Salmon <jsal...@thesalmons.org> wrote:
> I've got a class with a private copy constructor
> that I'd like to pass as a reference argument to a
> function.
> Gcc is unhappy with the following code unless I create an explicit
> temporary. Comeau's online compiler seems to think it's fine. It
> looks OK to me, too. Since the argument to func() is a reference to
> Foo, there's no need for the compiler to copy-construct a temporary.
> Or is there? Is gcc correct to complain? Or is comeau correct to
> accept this?
The current version of the standard says that g++ is correct in
rejecting it. I think that the current draft has been changed
to allow this, however.
--
James Kanze (GABI Software) email:james.ka...@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]