How to avoid ambiguous constructors?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jason Heyes

    How to avoid ambiguous constructors?

    I have a class with two constructors that both take the same type of
    argument as a parameter. What should I do to disambiguate my class?


  • Jason Heyes

    #2
    Re: How to avoid ambiguous constructors?

    "Jason Heyes" <geoffhys@optus net.com.au> wrote in message
    news:3fd064c6$0 $20308$afc38c87 @news.optusnet. com.au...[color=blue]
    > I have a class with two constructors that both take the same type of
    > argument as a parameter. What should I do to disambiguate my class?[/color]

    I just found one way to fix my ambiguous constructors. You need to add a
    dummy int parameter to one of the constructors. When you want to call that
    particular constructor, you specify a zero argument.


    Comment

    • Rolf Magnus

      #3
      Re: How to avoid ambiguous constructors?

      Jason Heyes wrote:
      [color=blue]
      > "Jason Heyes" <geoffhys@optus net.com.au> wrote in message
      > news:3fd064c6$0 $20308$afc38c87 @news.optusnet. com.au...[color=green]
      >> I have a class with two constructors that both take the same type of
      >> argument as a parameter. What should I do to disambiguate my class?[/color]
      >
      > I just found one way to fix my ambiguous constructors. You need to add
      > a dummy int parameter to one of the constructors. When you want to
      > call that particular constructor, you specify a zero argument.[/color]

      I'd rather use an enum to make the resulting code more readable:

      class Length
      {
      public:
      enum Unit { Centimeter, Inch };

      Length(double l, Unit u = Centimeter);

      //...
      };

      However, you will need to select (with if or switch/case) the code
      depending on the value.
      If you want two separate constructors, you can do it too with a small
      modification:

      class Length
      {
      public:
      enum Centimeter_t { Centimeter };
      enum Inch_t { Inch };

      Length(double l, Centimeter_t = Centimeter);
      Length(double l, Inch_t);

      //...
      };

      Now you can write:

      Length l1(3); // 3 centimeters, constructor 1
      Length l2(5, Inch); // 5 inches, constructor 2
      Length l3(7, Centimeter); // 7 centimeters, constructor 1

      If you leave out the default value, you can enforce the explicit
      specification of the unit, and the definition of l1 becomes invalid.

      Comment

      • jeffc

        #4
        Re: How to avoid ambiguous constructors?


        "Jason Heyes" <geoffhys@optus net.com.au> wrote in message
        news:3fd064c6$0 $20308$afc38c87 @news.optusnet. com.au...[color=blue]
        > I have a class with two constructors that both take the same type of
        > argument as a parameter. What should I do to disambiguate my class?[/color]

        The solution should actually present itself if you decide how the
        constructors are actually different. If you can't, then they are actually
        the same. When you identify under what conditions you would want one rather
        than the other, I think you'll find you can simply use the same one, but
        send a parameter that is a flag or enum to tell the constructor what to do
        differently when it is called with that parameter value. I doubt you really
        need more than one constructor.


        Comment

        • Brad Marts

          #5
          Re: How to avoid ambiguous constructors?

          On Fri, 05 Dec 2003 22:10:12 +1100, Jason Heyes wrote:
          [color=blue]
          > "Jason Heyes" <geoffhys@optus net.com.au> wrote in message
          > news:3fd064c6$0 $20308$afc38c87 @news.optusnet. com.au...[color=green]
          >> I have a class with two constructors that both take the same type of
          >> argument as a parameter. What should I do to disambiguate my class?[/color]
          >
          > I just found one way to fix my ambiguous constructors. You need to add a
          > dummy int parameter to one of the constructors. When you want to call that
          > particular constructor, you specify a zero argument.[/color]

          Sounds like what you want to do is have an argument that represents a mode
          of construction. Much the the fstream class takes an optional openmode as
          an argument. So instead of having two constructors, you have one which
          behaves differently based on the mode parameter.

          Brad

          Comment

          • Dan W.

            #6
            Re: How to avoid ambiguous constructors?

            On Fri, 5 Dec 2003 21:58:12 +1100, "Jason Heyes"
            <geoffhys@optus net.com.au> wrote:
            [color=blue]
            >I have a class with two constructors that both take the same type of
            >argument as a parameter. What should I do to disambiguate my class?
            >[/color]

            you could also make your two constructors explicit:

            class foo
            {
            explicit foo(int);
            explicit foo(unsigned int);
            };

            Comment

            • Ron Natalie

              #7
              Re: How to avoid ambiguous constructors?


              "Dan W." <danw@raytron-controls.com> wrote in message news:0oq1tvk3qp fmevn46u3nu9bi3 vjlhj1ubm@4ax.c om...
              [color=blue]
              >
              > you could also make your two constructors explicit:
              >
              > class foo
              > {
              > explicit foo(int);
              > explicit foo(unsigned int);
              > };[/color]

              How does this help? If it was ambiguious before it still is ambiguous.
              i.e.
              foo(1L); // still bad.


              Comment

              • Dan W.

                #8
                Re: How to avoid ambiguous constructors?

                On Fri, 5 Dec 2003 15:49:32 -0500, "Ron Natalie" <ron@sensor.com >
                wrote:
                [color=blue]
                >
                >"Dan W." <danw@raytron-controls.com> wrote in message news:0oq1tvk3qp fmevn46u3nu9bi3 vjlhj1ubm@4ax.c om...
                >[color=green]
                >>
                >> you could also make your two constructors explicit:
                >>
                >> class foo
                >> {
                >> explicit foo(int);
                >> explicit foo(unsigned int);
                >> };[/color]
                >
                >How does this help? If it was ambiguious before it still is ambiguous.
                >i.e.
                > foo(1L); // still bad.
                >[/color]

                DOH ! I was thinking with the wrong body parts... ;-)

                Comment

                • Rolf Magnus

                  #9
                  Re: How to avoid ambiguous constructors?

                  Dan W. wrote:
                  [color=blue]
                  > On Fri, 5 Dec 2003 15:49:32 -0500, "Ron Natalie" <ron@sensor.com >
                  > wrote:
                  >[color=green]
                  >>
                  >>"Dan W." <danw@raytron-controls.com> wrote in message
                  >>news:0oq1tvk3 qpfmevn46u3nu9b i3vjlhj1ubm@4ax .com...
                  >>[color=darkred]
                  >>>
                  >>> you could also make your two constructors explicit:
                  >>>
                  >>> class foo
                  >>> {
                  >>> explicit foo(int);
                  >>> explicit foo(unsigned int);
                  >>> };[/color]
                  >>
                  >>How does this help? If it was ambiguious before it still is
                  >>ambiguous. i.e.
                  >> foo(1L); // still bad.
                  >>[/color]
                  >
                  > DOH ! I was thinking with the wrong body parts... ;-)[/color]

                  Which body parts could be used for thinking about ambiguities?
                  Or was it the body part used to create new "objects"? ;-)

                  Comment

                  • E. Robert Tisdale

                    #10
                    Re: How to avoid ambiguous constructors?

                    Jason Heyes wrote:
                    [color=blue]
                    > I have a class with two constructors
                    > that both take the same type of argument as a parameter.
                    > What should I do to disambiguate my class?[/color]

                    Do you really need all of these constructors?
                    You can define *pseudo instructors* instead:

                    class foo { // thanks to Dan W.
                    private:
                    // representation
                    int I;
                    public:
                    // constructors
                    foo(int);
                    // functions
                    friend
                    foo pseudo(int);
                    };


                    int main(int argc, char* argv[]) {
                    foo F(13);
                    foo G = pseudo(33);
                    return 0;
                    }

                    If you have a good optimizing C++ compiler,
                    the pseudo constructor won't cost any more
                    than an actual constructor.

                    Comment

                    • E. Robert Tisdale

                      #11
                      Re: How to avoid ambiguous constructors?

                      E. Robert Tisdale wrote:
                      [color=blue]
                      > Jason Heyes wrote:
                      >[color=green]
                      >> I have a class with two constructors
                      >> that both take the same type of argument as a parameter.
                      >> What should I do to disambiguate my class?[/color]
                      >
                      >
                      > Do you really need all of these constructors?
                      > You can define *pseudo constructors* instead:
                      >
                      > class foo { // thanks to Dan W.
                      > private:
                      > // representation
                      > int I;
                      > public:
                      > // constructors
                      > foo(int);
                      > // functions
                      > friend
                      > foo pseudo(int);
                      > };
                      >
                      >
                      > int main(int argc, char* argv[]) {
                      > foo F(13);
                      > foo G = pseudo(33);
                      > return 0;
                      > }
                      >
                      > If you have a good optimizing C++ compiler,
                      > the pseudo constructor won't cost any more
                      > than an actual constructor.
                      >[/color]


                      Comment

                      Working...