How to avoid ambiguous constructors?

J

Jason Heyes

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?
 
J

Jason Heyes

Jason Heyes said:
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?

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.
 
R

Rolf Magnus

Jason said:
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.

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.
 
J

jeffc

Jason Heyes said:
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?

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.
 
B

Brad Marts

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.

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
 
D

Dan W.

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?

you could also make your two constructors explicit:

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

Ron Natalie

Dan W. said:
you could also make your two constructors explicit:

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

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

Dan W.

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

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

Rolf Magnus

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

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

E. Robert Tisdale

Jason said:
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?

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.
 
E

E. Robert Tisdale

E. Robert Tisdale said:
Jason said:
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?


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.
 

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,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top