473,401 Members | 2,139 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,401 software developers and data experts.

C++ says that these are ambiguous...

Hello, I have 2 classes *as an example* Point & Color and friend
operator * in the class Point is defined in such a way that it is
possible to do something like that Point p = Point( 1.0 ) * Color( 2.0
);

// in point.hpp
class Color;

class Point {
public:
float x, r, z;
Point( float xx ) : x( xx ), y( xx ), z( xx ) {}
friend Point operator * ( const Point &p, const Color &c )
{ return Point( p.x * c.x ); }
};

//in color.hpp
class Vector;
class Color {
public:
float r, g, b;
Point( float xx ) : r( xx ), g( xx ), b( xx ) {}
};

// so that line somwhere in the code works
Point p = Point( 1.0 ) * Color( 2.0 );

And it compile fine.

Now I tried to provide the Point vector with a constuctor where the
argument that is passed is a Color and rewrote the friend operator * to
take advantage of that:

class Point {
...
Point( const Color& c ) : x( c.r ), y( c.g ), z( c.b ) {}
Point operator * ( const Point& p ) { return Point( x * p.x, y * p.y,
z * p.z ); }
friend Point operator * ( const Point &p, const Color &c )
{ return p * Point( c ); }
};

But when I compile I get the following error message:

error: ISO C++ says that these are ambiguous, even though the worst
conversion for the first is better than the worst conversion for the
second:
../math/point.hpp:90: note: candidate 1: Point<floatoperator*(const
Point<float>&, const Color<float>&)
../math/point.hpp:55: note: candidate 2: Point<T>
Point<T>::operator*(const Point<T>&) [with T = float]

Basically the compile from what I understand the compiler doesn't know
if it needs to convert the color into a point and use the * operator or
to use the friend * operator and keep the right hand side argument as a
Color.

Could someone tell me what is the best way of doing that please ? Just
using constructors that allows explicit conversion of different types (
Color to Point ) and use the operator of the Point class, or not having
any explicit conversion in the Point class and only use the friend * (
Point, Color ) operator.

Thanks -

Aug 30 '06 #1
3 3277
LR
ma*****@yahoo.com wrote:
Hello, I have 2 classes *as an example* Point & Color and friend
operator * in the class Point is defined in such a way that it is
possible to do something like that Point p = Point( 1.0 ) * Color( 2.0
);

// in point.hpp
class Color;

class Point {
public:
float x, r, z;
Point( float xx ) : x( xx ), y( xx ), z( xx ) {}
friend Point operator * ( const Point &p, const Color &c )
{ return Point( p.x * c.x ); }
};

//in color.hpp
class Vector;
class Color {
public:
float r, g, b;
Point( float xx ) : r( xx ), g( xx ), b( xx ) {}
};

// so that line somwhere in the code works
Point p = Point( 1.0 ) * Color( 2.0 );

And it compile fine.
I very much doubt that the above will compile fine. One example, x is
not a member of Color. Another, you seem to have a ctor for Point as a
member of Color.
>
Now I tried to provide the Point vector
What is the Point vector? Are you trying to create a
std::vector<Point>? Are you refering to your class Vector? If so, what
is it?
with a constuctor where the
argument that is passed is a Color and rewrote the friend operator * to
take advantage of that:

class Point {
...
Point( const Color& c ) : x( c.r ), y( c.g ), z( c.b ) {}
Point operator * ( const Point& p ) { return Point( x * p.x, y * p.y,
z * p.z ); }
friend Point operator * ( const Point &p, const Color &c )
{ return p * Point( c ); }
};

But when I compile I get the following error message:

error: ISO C++ says that these are ambiguous, even though the worst
conversion for the first is better than the worst conversion for the
second:
./math/point.hpp:90: note: candidate 1: Point<floatoperator*(const
Point<float>&, const Color<float>&)
./math/point.hpp:55: note: candidate 2: Point<T>
Point<T>::operator*(const Point<T>&) [with T = float]
Are these error messages being produced for template classes? Well, I'm
not exactly sure what's wrong, but you may be able to fix the problem by
changing this:

Point operator * ( const Point& p ) {
return Point( x * p.x, y * p.y, z * p.z );
}

to this:

friend Point operator*(const Point &p1, const Point &p2) { ... }
>
Basically the compile from what I understand the compiler doesn't know
if it needs to convert the color into a point and use the * operator or
to use the friend * operator and keep the right hand side argument as a
Color.

Could someone tell me what is the best way of doing that please ? Just
using constructors that allows explicit conversion of different types (
Color to Point ) and use the operator of the Point class, or not having
any explicit conversion in the Point class and only use the friend * (
Point, Color ) operator.
I think this question may be a little bit beyond me, but I think the
answer will be, It Depends.

What will be the effect of having ctors that convert? Will that have
some bad unforeseen consequences later?

How tightly coupled are Color and Point?
Why are they two seperate classes?

Would you be better off having a function:
Point PointFromColor(const Color &c) { return Point(....); }
and then..
Point p = point * PointFromColor(color);

What is it that you are trying to communicate to someone who might read
your code?

LR
Aug 30 '06 #2

ma*****@yahoo.com wrote:
Hello, I have 2 classes *as an example* Point & Color and friend
operator * in the class Point is defined in such a way that it is
possible to do something like that Point p = Point( 1.0 ) * Color( 2.0
);
That doesn't make sense. A point is a Point and a Color is a Color. Are
you trying to create a derived ColouredPoint class? If you are then
surely Color is an attribute of the ColouredPoint. A Color is_not a
Point.

<clipped>
Could someone tell me what is the best way of doing that please ? Just
using constructors that allows explicit conversion of different types (
Color to Point ) and use the operator of the Point class, or not having
any explicit conversion in the Point class and only use the friend * (
Point, Color ) operator.
Take a look at the following and then explain what you are trying to
get, cause i still don't follow the question.

// proj_color.cpp : Defines the entry point for the console
application.
//

#include <iostream>
#include <ostream>
#include <vector>

class Point
{
int x, y, z;
public:
Point() : x(0), y(0), z(0) { } // default ctor
Point( int x_, int y_, int z_ ) : x(x_), y(y_), z(z_) { }
virtual ~Point() { }
};

class Color
{
float r, g, b;
public:
Color( ) : r(0), g(0), b(0) { } // default ctor
Color( float r_, float g_, float b_ ) : r(r_), g(g_), b(b_) { }
~Color() { }
/* friend op<< */
friend std::ostream& operator<<(std::ostream& os, const Color& r_c)
{
os << "r = " << r_c.r;
os << " g = " << r_c.g;
os << " b = " << r_c.b;
return os << "\n";
}
};

class ColoredPoint : public Point
{
Color color; // composition
public:
ColoredPoint() : color() { } // default ctor
ColoredPoint( int x_, int y_, int z_, float r_, float g_, float b_ )
: Point(x_, y_, z_), color(r_, g_, b_) { }
/* member functions */
Color getColor() const { return color; }
};

int main()
{
std::vector< ColoredPoint* vpoints;

vpoints.push_back( new ColoredPoint );
vpoints.push_back( new ColoredPoint( 1,1,1,128.0,128.0,128.0) );

Color color_origin = vpoints[0]->getColor(); // default color
std::cout << "color_origin is " << color_origin;
Color color_test = vpoints[1]->getColor(); // medium gray
std::cout << "color_test is " << color_test;

typedef std::vector< ColoredPoint* >::iterator VIter;
VIter iter = vpoints.begin();
for( iter; iter != vpoints.end(); ++iter )
{
delete *iter;
}
return 0;
}

/*
color_origin is r = 0 g = 0 b = 0
color_test is r = 128 g = 128 b = 128
*/

Aug 31 '06 #3
In article <11**********************@m73g2000cwd.googlegroups .com>,
pj*****@yahoo.com says...

[ ... ]
That doesn't make sense. A point is a Point and a Color is a Color.
Depending on the situation, it's often useful to think of a color as a
point in a 3D color-space. When writing things like shaders for 3D
hardware, you often want to treat the two interchangeably as well.

At the same time, you're right that derivation is probably a problem
here. You can't substitute any random point in all situations that call
for a color or vice versa.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Sep 2 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Alex Vinokur | last post by:
Why is it ambiguous? ------ foo.cpp ------ struct Foo { Foo operator* (Foo) { return Foo(); } Foo operator* (int) const { return Foo(); } Foo () {} Foo (int) {} };
16
by: REH | last post by:
Can some tell me why the chooses the constructor in class B over operator B in class A? Is this not ambiguous? Thanks. #include <iostream> using namespace std;
2
by: Julia Baresch | last post by:
Hi everyone, My database has 3 data tables with chained one-to-many relationships i.e. Table1 1-->Many ->Table2 1-->Many ->Table3 I added a fourth table to hold supplemental data that also...
0
by: Stephen Cairns | last post by:
I have the following rpx file in a .Net solution and I am getting the following build errors which are driving me crazy and ive no idea where I have went wrong. The build errors I'm getting are as...
3
by: Lee Gillie | last post by:
I have a VS6 project which I brought into VS .NET, and all has been building fine. Then I upgraded to VS 2003 and I have one source which will no longer compile. Any clues? Compiling......
9
by: Prasad | last post by:
HI, I am a beginner in VC++.. I am trying to write a Win32 console application in visual studio.. I am using following header files.. #include <STRING> using namespace std; #include...
1
by: rn5a | last post by:
Consider the following code in a VB class file: Namespace LoginUserFetchDB Public Class ZForZebra : Inherits SoapHeader Public UserName As String Public Password As String End Class Public...
8
by: xtrigger303 | last post by:
Hi to all, I'm working on a smart pointer implementation and I'm trying to get automatic type conversion between different pointer types. I stumbled upon something weird (at least for me) I...
12
by: Nathan Sokalski | last post by:
I have several CustomControls that I have written for my project. However, when I try to compile I recieve the following warning & errors: Warning 32 Could not resolve this reference. Could not...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.