822. Object with explicit copy constructor no longer CopyConstructible

  • Permalink
  • submit to reddit
  • Email
  • Follow


Hi All,

 From the latest Standard Library active issues list:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2806.html

"
I just noticed that the following program is legal in C++03, but is
forbidden in the current draft:

     #include <vector>
     #include <iostream>

     class Toto
     {
     public:
         Toto() {}
         explicit Toto( Toto const& ) {}
     } ;

     int
     main()
     {
         std::vector< Toto > v( 10 ) ;
         return 0 ;
     }

Is this change intentional? (And if so, what is the justification? I
wouldn't call such code good, but I don't see any reason to break it
unless we get something else in return.)
"

1.  I don't understand why the program is now illegal.  std::vector
still offers a single int constructor that only requires its type to be
default constructable.  Does the explicit copy constructor make the
default constructor not visible?  Is this a language change or a library
change -- if the former, why is this issue in the Library Issues?

2.  Why is the code bad?  Is it because of the explicit copy
constructor?  Could that be a funny way of suppressing assignment form
initializers?  Or is it a no-op?


Geno Rice

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Eugene 12/12/2008 6:55:12 PM

See related articles to this posting


On 13 Dez., 01:55, Eugene Rice <g...@verizon.net> wrote:
>  From the latest Standard Library active issues list:
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2806.html
>
> "
> I just noticed that the following program is legal in C++03, but is
> forbidden in the current draft:
>
>      #include <vector>
>      #include <iostream>
>
>      class Toto
>      {
>      public:
>          Toto() {}
>          explicit Toto( Toto const& ) {}
>      } ;
>
>      int
>      main()
>      {
>          std::vector< Toto > v( 10 ) ;
>          return 0 ;
>      }
>
> Is this change intentional? (And if so, what is the justification? I
> wouldn't call such code good, but I don't see any reason to break it
> unless we get something else in return.)
> "
>
> 1.  I don't understand why the program is now illegal.  std::vector
> still offers a single int constructor that only requires its type to be
> default constructable.  Does the explicit copy constructor make the
> default constructor not visible?  Is this a language change or a library
> change -- if the former, why is this issue in the Library Issues?

The reason, why it is now excluded, is, because the definition of
the requirement CopyConstructible has changed. This happened with
the introduction of the new requirement MoveConstructible as of

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2284.pdf

Interestingly previous papers correctly took into account possibly
explicit c'tors, just compare with

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1771.html

IMO the current concepts related to "constructor" concepts
have the problem, that starting from the most fundamental
constructor-related concept is non-explicit, see 20.2.6 in
N2798:

auto concept HasConstructor<typename T, typename... Args> {
   T::T(Args...);
}

This is a basic weakness, because this would not make
it possible to express any explicit constructor by the
concepts std::HasConstructor, std::Constructible,
std::MoveConstructible, or std::CopyConstructible.
It also makes it impossible to let existing concepts
like std::ArithmeticLike fulfill std::HasConstructor,
which itself requires (at least) explicit c'tors:

explicit T::T(intmax_t);
explicit T::T(uintmax_t);
explicit T::T(long double);

This becomes obvious, if you compare this situation
with the example shown in [concept.map.fct]/4,
bullet 12:

concept IC<typename T> {
   T::T(int);
}
concept EC<typename T> {
   explicit T::T(int);
}
struct X {
   X(int);
};
struct Y {
   explicit Y(int);
};
concept_map IC<X> { } // OK
concept_map EC<X> { } // OK
concept_map IC<Y> { } // error: cannot copy-initialize Y from an int
concept_map EC<Y> { } // OK

So, the current draft definitively has to fix the
current hierarchy of library concepts described
in [utility.concepts].

> 2.  Why is the code bad?  Is it because of the explicit copy
> constructor?  Could that be a funny way of suppressing assignment form
> initializers?  Or is it a no-op?

Explicit copy constructors have some funny and sometimes
astonishing properties, e.g. the fact, that you cannot
invoke a function taking a type with such copy constructor
by value:

struct S {
   S(){}
   explicit S (S const&){}
} s;

void f(S){}

void g() {
     f(s); // Error
}

This constraint makes using such types with most
libraries (including the standard library) a pain.
If you would e.g. provide a functor or an iterator
with explicit copy constructor, it could never be
used with the manifold of algorithms provided by
[algorithms], because these basically always take
the arguments by value. Such functions have many
advantages and if you want to define a constexpr
function (a new feature for C++0x) you are required
to take arguments by value there.

HTH & Greetings from Bremen,

Daniel Kr�gler


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply daniel 12/13/2008 4:16:22 PM
comp.lang.c++.moderated 10649 articles. 9 followers. Post

1 Replies
169 Views

Similar Articles

[PageSpeed] 30


  • Permalink
  • submit to reddit
  • Email
  • Follow


Reply:

Similar Artilces:

converting constructor and explicit copy constructor
This is a question about the interaction between converting constructor and explicit copy constructor when copy-initializing an object. class C { public: explicit C(const C&) {} C(int i) {} }; int main() { C c1(1); // no problem C c2 = 2; // Comeau on-line 4.3.3b ok; cygwin gcc 3.3.3 error. } c2 is copy-initialized. Semantically, C(int i) will be called implicitly to convert 2 to a temporary C object, and then C(const C&) will also be called implicitly to construct c2. But since C(const C&) is declared as explicit. So this will fail. I think this is the reas...

deep/shallow copy
Is there any kind of convention that dictates where it is usual to perform shallow and deep copies? I prefer to use copy constructors to implement any kind of copy, but now I find the need for a shallow and deep copy in the same class. I haven't ever needed to implement copy(), I imagine that its purpose is for RTTI. -- Mike W "VisionSet" <spam@ntlworld.com> wrote in message news:s3Uic.166$cy3.127@newsfe1-win... > Is there any kind of convention that dictates where it is usual to perform > shallow and deep copies? > I prefer to use copy constructors to impleme...

Copy constructor: why can't I copy objects as if they were structs?
Hello! Is this too crazy or not? Copy constructor: why can't I copy objects as if they were structs? I have a set of simple objects (no string properties, just integers, doubles) and I have to copy the same object millions of times. So instead of writing in the copy constructor property1=SourceObject.property1 can't I use memory copy functions to do this faster? Is this too stupid? By the way, I'm a C++ newbie! But don't go easy on me just because... ;) Bye! Thanks for your help and attention. Jorge C. rdc02271@yahoo.com rdc02271 wrote: > Is this too crazy or not? > C...

explicit copy constructors.
Question: The following code doesn't work on the solaris 10 compiler: class X { public: X( int x); explicit X(const X&); }; X f() { X obj; return obj; // change here } int main() { X m = foo(); } get an error Cannot use X to initialize X. When explicit is taken off the copy constructor it works. While I plan on removing the explicit keyword I was wondering if someone could explain why the code above doesn't work but if I "return X(obj);" it does what. What rules in the standard are being used to allow the latter but not the forme...

explicit copy constructors
Hello NG, Can anybody fathom the purpose of an explicit copy constructor? On page 232 of the Josuttis STL reference, I see a reference to such. How could you ever need to supress the possibility of an implicit conversion from type T to type T? Such an implicit conversion could never occur because you're already of the required type! Thanks, Dave Dave wrote: > Can anybody fathom the purpose of an explicit copy constructor? On page 232 > of the Josuttis STL reference, I see a reference to such. > > How could you ever need to supress the possibility of an implicit conver...

Explicit copy constructor
Hi, gcc 3.4 rejects the following program: class T { public: T() : a(3) {} explicit T(T const & other) : a(other.a) {} private: int a; }; void func(T const & obj) { } int main() { func(T()); } The error is: no matching function for call to `T::T(const T&)' There is some reasoning about it at: http://gcc.gnu.org/bugs.html#cxx_rvalbind This seems to be correct for private copy constructors, but I am not sure whether the interpretation by the gcc team also applies to explicit copy constructors. Is there some discussion about the correct interpretation of the s...

explicit copy constructor #3
Hi, folks, I am trying to make my copy constructor explicit, but when the scenario below comes into being, weird things happen. Here is the code snippet: #include <iostream> using namespace std; class Base { public: Base() { } Base(const Base& other) { } }; template<typename T> class Derived: public Base { public: Derived() { } template<typename U> Derived(const Derived<U>& other): Base(*(Base*)&other) { cout << "Cast copy constructor\n"; } //here is the trouble maker explicit Derive...

How to explicitly allow object copy ?
Hi. I would like to explicitly allow object copy, without writting a user defined copy constructor. I am looking for something like : class C { public: C(const C &c) { /* call compiler define copy constructor */ } }; Is there any way to do that in C++ ? Thank you for advance. Note that I would also find useful to do : class C { public: C(const C &c) { /* call compiler define copy constructor */ ; /* do someting more */; } }; frjm31-groups@yahoo.fr wrote: > > Hi. > > I would like to explicitly allow object copy, without writting a user > defined copy co...

Copy Constructor and explicit attribute
Hi ! I tried to understand when the explicit attribute in copy constructor prevents from me to create a new object. Bellow is the sample code. While the two first cases really generate a compilation error, the third (mc2 = Foo1();) compiles and runs without any problem. I am wondering why the: MyClass Foo1() { MyClass mc(1); return mc; } isn't forbidden, when MyClass copy constructor is defined as explicit. Thanks. class MyClass { public: MyClass(int nVal) : m_nVal1(nVal){} MyClass() : m_nVal1(0){} explicit MyClass(const MyClass& copy) { //... } private: int m_nVal1; ...

A question on explicit copy constructors
Hi, friends, i've just encountered a problem on explicit copy constructors, my friend was read that when a function returns a object by value, the object can be created outside the function if it is returned in the way "return-and-copy-construct", so one can prevent temporary object being created once inside the function and again when the function returns the same object, the code example can be this: #include <iostream> using namespace std; struct foo { foo() { cout << "contructor called.\n"; } foo(const foo& f) { cout << "copy-construct...

Copy Constructor And Temporary Objects
Hi! I have stumbled upon an interesting feature when passing objects "by value" to functions. Let's say I have the following class: class Class1 { public: Class1(); ~Class1(); }; And I have two functions that deal with objects from that class: Class1 func1() { Class1 x; return(x); } void func2(Class1& aa) { } So, my objective is passing the return value of "func1" as an argument to "func2", but doing this directly does not work, that is: func2(func1()); //!ERROR BUT, if I define the argument of "func2" as a "const Cl...

explicit copy constructor #2
Hello, I noticed the following in the "C++ Coding Standards" book. Why should the code on line 30 be in error? Transmogrify accepts a (B obj), and we are passing it a B obj. I understand why the other call to transmogrify failed: we disallowed implicit conversion D->B with a keyword 'explicit'. Or, does the call Transmogrify( b ); mean that a copy constructor still gets invoked - implicitly (which is what explicit is supposed to disallow)? Thank you very much. 10 // Making the copy constructor explicit (has side effects, needs improvement) 11 class B {// ... 12 p...

"explicit" copy constructors
It just crossed my mind tonight that if a class's copy constructor is declared explicit, many cases of accidental object slicing will fail to compile: class Base { public: explicit Base(){} explicit Base(const Base&){} }; class Der: public Base {}; void foo(const Base){} // suspect function declaration due to // pass-by-value of the param Der d; foo(d); // won't compile -- d is of wrong type This seems at least mildly neat, though VC7.1 lets the code through anyway. (Gcc 3.2 and Comeau...

Creating a pair of objects with no copy constructor?
Hi, Assume I have the following class class test{ public: int x; test(){ x = 5; } private: test(test& v){ x = v.x; } }; now, i need to create a pair of this object pair<test,test>(??,??) what should I put in the constructor to allow me to construct such a pair? All attempts fail because copy constructor is disallowed. Thank you very much responsible wrote: > Assume I have the following class > > class test{ > public: > int x; > test(){ > x = 5; > } > private: > test(test& v){ > x = v.x; > } > }; > >...

explicit call to copy constructor and operator = needed
Why do we need to explicitly call the copy constructor and the operator = , for base class and member objects in composition? ....book says "You must explicitly call the GameBoard copy-constructor or the default constructor is automatically called instead" Why cant the compiler do this on its own. if we are making an object through copr construction for an inherited class , then why not simply call the corresponding copy constructors for base class objects or composed objects ? class GameBoard { public: GameBoard() { cout << "GameBoard()\n"; } GameBoard(co...

no matching function for call to explicit copy-constructor
Trying to compile the following code-fragment with g++ 2.96: class Entity { private: void * data; public: explicit Entity(int); explicit Entity(Entity &); virtual ~Entity(); void makeSomething(); }; Entity f(int n) { Entity result(n); result.makeSomething(); return result; } I obtain the error: no matching function for call to `Entity::Entity (Entity &)' on the the row: return result; It's a my fault? The only way to get away from the error is to change the copy constructor into: /* explicit */ Entity(Entity &); But I want to use ex...

C++0X explicitly defaulted copy constructors
See below for the code. A variadic argument U&&... matches a copy-from-lvalue better than the implicit copy constructors, so I need to declare a copy constructor from lvalue. And since its existence prevents the implicit declaration of the other two versions (from const ref and from rvalue), I need to declare those 2 as well. Now I don't want anything fancy for those and I am fine with whatever the compiler can generate by default, so I default the three copy/move constructors. Now, according to g++, I am only allowed to specify "=default" inside the class for 2...

Should std::swap be disabled by an explicit copy constructor?
A careful programmer might want to disable std::swap for her class, e.g., because her class has a throwing assignment. Now it seems that disabling std::swap is achieved by declaring the copy constructor of this class explicit! Indeed, the following program is rejected by all compilers and std library implementations I tried sofar, including MSVC++ 8.0, GNU g++ 3.4.4, Comeau C++ 4.3.3 online (www.comeaucomputing.com), and Dinkumware (www.dinkumware.com/exam) //////////////////////////////////////////////////////////////////////// #include <algorithm> #include <vector&...

define a copy constructor in a class having data member as an object of another class
Hi, can anyone help me by writing a sample code of defining a copy constructor in a class having data member as an object of another class. for eg: class A{ int x; public: A(){ x=6;} }; class B{ A a1; public:B(B &b1) { ???} //how i can assign the data members?? }; Any idea ...Thanks -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] The contained object itself should have copy constructor and assignment operator defined unless the object is a POD (plain old data) type. On Nov 9, 4:12 pm, dal...

define a copy constructor in a class having data member as an object of another class
Hi, can anyone help me by writing a sample code of defining a copy constructor in a class having data member as an object of another class. for eg: class A{ int x; public: A(){ x=6;} }; class B{ A a1; public:B(B &b1) { ???} //how i can assign the data members?? }; Any idea ...Thanks dalu.gelu@gmail.com wrote: > Hi, > can anyone help me by writing a sample code of defining a copy > constructor in a class having data member as an object of another > class. > for eg: > class A{ > int x; > public: A(){ x=6;} > }; > > class B{ > A a1; > public:B(B &a...

Objects returned by value don't use copy constructors!
Hi, I thought that a copy constructor has to be involved, when a function returns an object by value. It doesn't have to be so, as shown by running the code at the end of my email (I used GCC 3.4.6 on Linux). Run the code, and you'll see that the copy constructor is not called, and that the destructor is called only once. Before running the code I expected to see the copy constructor called once, and the destructor twice. I would appreciate an explanation why this happens. Thanks, Irek -- Ireneusz (Irek) Szczesniak http://www.irkos.org ****************************************...

returning an object by value using a non const copy constructor argument
Hi, I was wondering how to get the following working. I know std::auto_ptr does something similar but how ? Thanks, Ralph. class Test { public: Test() : m_b(true) {}; // copy constructor which resets the object beeing copied Test(Test &t) : m_b(t.m_b) { t.m_b = false; }; bool get() const { return m_b; }; private: bool m_b; }; Test f() { // this will not compile... return Test(); } On Jun 11, 3:07 pm, Ralph wrote: > class Test > { > public: > Test() : m_b(true) {}; > > // copy ...

Why aren't "explicit" constructors ignored when using {...} copy initialization?
I've wondered all days long but I can't come up with a satisfactory reason for why the draft is worded as it is. Why is the following an ambiguous function call? struct MyList { explicit MyStore(int initialCapacity); }; struct MyInt { MyInt(int i); }; struct Printer { void operator()(MyStore const& s); void operator()(MyInt const& i); }; void f() { Printer p; p({23}); } Why is the explicit constructor not ignored? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First t...

Copy constructor doesn't get called when initialized by function returning object of same class
I am bit puzzled at the following piece of code I tried: ---------------------------------------------------------------------------------- #include <iostream> using namespace std; class Test { public: Test() { cout<<"Cons\n";} Test(Test& a) { cout<<"Copy cons\n";} }; Test fun() { return Test(); } int main() { cout<<"First way of initialization\n"; Test t1; Test t2 = t1; cout<<"\nSecond way of initialization\n"; Test t3 = fun(); return 0; } OUTPUT (when compiled on CC compiler) : First way of ...