Explicit copy constructor

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Christoph Bartoschek

    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:



    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 standard for explicit copy constructors?

    Christoph Bartoschek
  • Victor Bazarov

    #2
    Re: Explicit copy constructor

    "Christoph Bartoschek" <bartoschek@gmx .de> wrote...[color=blue]
    > 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 standard for explicit copy constructors?[/color]

    Explicit constructor requires the direct initialiser syntax or
    an explicit cast. Creation of a temporary from an r-value for
    binding a temporary (even if it's not done that way) is all
    implicit. It seems that if copy-constructor is declared explicit
    would prevent a temporary object from initialising (since no
    syntax can be used for that).

    Why would you want to have the copy c-tor explicit?

    Victor


    Comment

    • Dave Moore

      #3
      Re: Explicit copy constructor

      Christoph Bartoschek <bartoschek@gmx .de> wrote in message news:<vs23m1-j76.ln1@ID-80222.user.uni-berlin.de>...[color=blue]
      > 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 standard for explicit copy constructors?
      >
      > Christoph Bartoschek[/color]

      The whole point of declaring a constructor explicit is that it can
      only be called *explicitly*:

      T apple;
      T orange(apple);

      Your code is generating an *implicit* copy constructor call, thus the
      behavior makes sense using the logic laid out in the gcc document.
      Specifically, the proper semantics for the copy constructor call are
      not being obeyed in your case since the copy constructor is being
      called implicitly.

      HTH, Dave Moore

      P.S. Why do you want an explicit copy constructor?

      Comment

      • DaKoadMunky

        #4
        Re: Explicit copy constructor

        >class T {[color=blue]
        >public:
        > T() : a(3) {}
        > explicit T(T const & other) : a(other.a) {}
        >private:
        > int a;
        >};
        >
        >void func(T const & obj) {
        >}
        >
        >int main() {
        > func(T());
        >}[/color]

        I don't understand how the error is being generated.

        Where is a copy-constructor being called implicitly in this code?

        What am I missing?

        I can tell you that this code compiled at www.comeaucomputing.com using their
        online compiler.

        Comment

        • Michiel Salters

          #5
          Re: Explicit copy constructor

          Christoph Bartoschek <bartoschek@gmx .de> wrote in message news:<vs23m1-j76.ln1@ID-80222.user.uni-berlin.de>...[color=blue]
          > 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 standard for explicit copy constructors?[/color]

          Yes, CWG issue 152. It changed between C++98 and C++03.

          The new rules are:

          When objects of class type are direct-initialized (8.5 dcl.init), or
          copy-initialized from an expression of the same or a derived class
          type (8.5 dcl.init), overload resolution selects the constructor. For
          direct-initialization, the candidate functions are all the
          constructors of the class of the object being initialized. For
          copy-initialization, the candidate functions are all the converting
          constructors (12.3.1 class.conv.ctor ) of that class.

          A non-explicit copy constructor (12.8 class.copy) is a converting
          constructor.

          This form requires copy-initialization to copy the temporary to the
          bound argument (although the actual copy may be optimized out). In
          this case, there's no converting ctor available.

          Regards,
          Michiel Salters

          Comment

          • Christoph Bartoschek

            #6
            Re: Explicit copy constructor

            Victor Bazarov wrote:

            ....
            [color=blue]
            > Why would you want to have the copy c-tor explicit?[/color]

            This was not my decision. But:

            We have a a class Node which is can be copied and used as a POD. However the
            addresses of objects of Node are used as indexes for the interface of the
            underlying C subsystem. 95% of all uses of Node are in conjunction with
            this subsystem. Most mistakes when using this system came from constructs
            like this:

            Node node = bla.get_node();
            subsystem_get_p arent(handle(no de));

            It is hard to find such an error. Therefore it was decided, that the copy
            constructor of Node becomes explicit to avoid such mistakes. Now each time
            one forgets the reference character the compiler complains.

            Christoph Bartoschek

            Comment

            • Christoph Bartoschek

              #7
              Re: Explicit copy constructor

              Michiel Salters wrote:
              ....
              [color=blue]
              > Yes, CWG issue 152. It changed between C++98 and C++03.
              >
              > The new rules are:
              >
              > When objects of class type are direct-initialized (8.5 dcl.init), or
              > copy-initialized from an expression of the same or a derived class
              > type (8.5 dcl.init), overload resolution selects the constructor. For
              > direct-initialization, the candidate functions are all the
              > constructors of the class of the object being initialized. For
              > copy-initialization, the candidate functions are all the converting
              > constructors (12.3.1 class.conv.ctor ) of that class.
              >
              > A non-explicit copy constructor (12.8 class.copy) is a converting
              > constructor.
              >
              > This form requires copy-initialization to copy the temporary to the
              > bound argument (although the actual copy may be optimized out). In
              > this case, there's no converting ctor available.[/color]

              Thanks, this argumentation was convincing.

              Christoph Bartoschek

              Comment

              Working...