473,385 Members | 1,813 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,385 software developers and data experts.

[VC++ 6.0] Ambiguous call to overloaded function

Hi,

Maybe somebody has been fighting with the problem that I do, currently.
I have a class that has method f(). The two versions of the f() method
accept different objects: Int and Short. These objects have
constructors that allow implicit conversions from simple types. All
this has been defined as follows:

<code>
class Int
{
public:
Int(const int);
};

class Short
{
public:
Short(const short);
};

class AClass
{
public:
void f(const Int &);
void f(const Short &);
};
</code>

Further, in the code, I have a following invocation:

<code>

AClass().f( 1 ); // <--- It is important that the type is int here!

</code>

But the compiler (VC++ 6.0) says:
error C2668: 'f' : ambiguous call to overloaded function

My question is why? Do I understand C++ implicit type conversion
imcorrectly or M$ makes sbth wrong?

TIA

--
Roland

Jul 4 '06 #1
5 10966
* rolandz:
Hi,

Maybe somebody has been fighting with the problem that I do, currently.
I have a class that has method f(). The two versions of the f() method
accept different objects: Int and Short. These objects have
constructors that allow implicit conversions from simple types. All
this has been defined as follows:

<code>
class Int
{
public:
Int(const int);
};

class Short
{
public:
Short(const short);
};

class AClass
{
public:
void f(const Int &);
void f(const Short &);
};
</code>

Further, in the code, I have a following invocation:

<code>

AClass().f( 1 ); // <--- It is important that the type is int here!

</code>

But the compiler (VC++ 6.0) says:
error C2668: 'f' : ambiguous call to overloaded function

My question is why?
Either choice of function to call involves one user-defined conversion.

Do I understand C++ implicit type conversion
imcorrectly
Probably.

or M$ makes sbth wrong?
Probably... ;-) But not here.

You can write

AClass.f( Int( 1 ) );

to disambiguate.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 4 '06 #2
Alf P. Steinbach napisal(a):
Maybe somebody has been fighting with the problem that I do, currently.
I have a class that has method f(). The two versions of the f() method
accept different objects: Int and Short. These objects have
constructors that allow implicit conversions from simple types. All
this has been defined as follows:

<code>
class Int
{
public:
Int(const int);
};

class Short
{
public:
Short(const short);
};

class AClass
{
public:
void f(const Int &);
void f(const Short &);
};
</code>

Further, in the code, I have a following invocation:

<code>

AClass().f( 1 ); // <--- It is important that the type is int here!

</code>

But the compiler (VC++ 6.0) says:
error C2668: 'f' : ambiguous call to overloaded function

My question is why?
You can write
AClass.f( Int( 1 ) );
This is exactly what I do not want to do... I want it to be transparent
for a user. The purpose is to provide a way to collect parameters in
some internal array of pointers in the AClass. But the parameters MUST
be allocated on stack (not heap) for performance reason.

The Int and Short classes are ment to be such wrappers on simple types
that are being allocated on stack. The conversion was designed for
transparent conversion so user even does not neet to know it.

--
Roland

Jul 4 '06 #3
* rolandz:
Alf P. Steinbach napisal(a):
>You can write
> AClass.f( Int( 1 ) );

This is exactly what I do not want to do... I want it to be transparent
for a user. The purpose is to provide a way to collect parameters in
some internal array of pointers in the AClass. But the parameters MUST
be allocated on stack (not heap) for performance reason.

The Int and Short classes are ment to be such wrappers on simple types
that are being allocated on stack. The conversion was designed for
transparent conversion so user even does not neet to know it.
That doesn't make much sense.

Most probably you have a case of Premature Optimization, where every
which way you're turning the language rules seem to try to stop you
(because they're designed for meaningful code).

Perhaps post a small program that compiles and illustrates what you're
trying to do.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.

Q: What is the most annoying thing on usenet and in e-mail?
Jul 4 '06 #4
Alf P. Steinbach napisal(a):
The Int and Short classes are ment to be such wrappers on simple types
that are being allocated on stack. The conversion was designed for
transparent conversion so user even does not neet to know it.

That doesn't make much sense.

Most probably you have a case of Premature Optimization, where every
which way you're turning the language rules seem to try to stop you
(because they're designed for meaningful code).

Perhaps post a small program that compiles and illustrates what you're
trying to do.
There are plenty of files, classes and interfaces. Following are the
most close to the problem, I think:

<code file="Operators.h">
Core::ILogMessage & operator << (Core::ILogMessage & msg,
const Impl::Serialization::ValueType::Byte & value);
Core::ILogMessage & operator << (Core::ILogMessage & msg,
const Impl::Serialization::ValueType::Int16 & value);
Core::ILogMessage & operator << (Core::ILogMessage & msg,
const Impl::Serialization::ValueType::Int32 & value);
Core::ILogMessage & operator << (Core::ILogMessage & msg,
const Impl::Serialization::ValueType::String & value);
Core::ILogMessage & operator << (Core::ILogMessage & msg,
const Impl::Serialization::ValueType::UInt16 & value);
Core::ILogMessage & operator << (Core::ILogMessage & msg,
const Impl::Serialization::ValueType::UInt32 & value);
</code>

There are more operators for more types - I've removed them from an
example...

<code file="Operators.cpp">
Core::ILogMessage & operator << (Core::ILogMessage & msg,
const Impl::Serialization::ValueType::Int16 & value)
{
msg.add(value);
return msg;
}
Core::ILogMessage & operator << (Core::ILogMessage & msg,
const Impl::Serialization::ValueType::Int32 & value)
{
msg.add(value);
return msg;
}
</code>

<code file="ILogMessage.h">
namespace Core
{
class ILogMessage : virtual public Core::Serialization::ISerializable
{
public:
virtual void add(const Core::Serialization::ISerializable & obj) = 0;

};
}
</code>

<code file="Int16.h">
namespace Impl
{
namespace Serialization
{
namespace ValueType
{
class Int16 : public Core::Serialization::ISerializable
{
short value;

public:
Int16(const short _value);

// Serializes object's data into a given stream
void serialize(Core::Serialization::IWriteStream *stream) const;

// Deserializes all object's data from a given stream
void deserialize(Core::Serialization::IReadStream *stream);
};
}
}
}
</code>

<code file="Int32.h>
namespace Impl
{
namespace Serialization
{
namespace ValueType
{
class Int32 : public Core::Serialization::ISerializable
{
long value;

public:
Int32(int _value);

// Serializes object's data into a given stream
void serialize(Core::Serialization::IWriteStream *stream) const;

// Deserializes all object's data from a given stream
void deserialize(Core::Serialization::IReadStream *stream);
};
}
}
}
</code>

There are also other types being defined identically as follows:

Byte - unsigned char
String - char *
UInt16 - unsigned short
UInt32 - unsigned long

Then I have a main file with following code:
<code file="Main.cpp">
Core::ILog * log = Impl::LogManager::get()->getLog("main");
for(unsigned long i = 0; i < 10000; ++i)
{
log->addLogEntry(Impl::Critical, &(Impl::Msg::ErrorMsg("Error %i, %s")
<< i )); // <=== There MUST be conversion.
}
</code>

Let me clarify the add() method in the ILogMessage interface
implementation that exists in the project. It stores passed parametes
as a pointer in the internal array of ISerializable pointers. Because
there is a constraint in the ILog interface implementation that stops
processing if the logging level is insufficient at the moment. Thus I
don't want to make any other activity than just temporarily store
passed arguments. They will be used if necessary.

Why on the stack? Because addLogEntry() method is to be invoked
extreamly often and operator new() introduces too much cost for
managing the arguments as well as it wuld introduce high heap
fragmentation.

If this description is insufficient for you I can prepare some small
demo project but it might cost some effort I want to avoid :|

Thanks for your attention :)

Jul 4 '06 #5
"rolandz" <ro*****@poczta.fmwrote in message
news:11**********************@p79g2000cwp.googlegr oups.com...
Hi,

Maybe somebody has been fighting with the problem that I do, currently.
I have a class that has method f(). The two versions of the f() method
accept different objects: Int and Short. These objects have
constructors that allow implicit conversions from simple types. All
this has been defined as follows:

<code>
class Int
{
public:
Int(const int);
};

class Short
{
public:
Short(const short);
};

class AClass
{
public:
void f(const Int &);
void f(const Short &);
};
</code>

Further, in the code, I have a following invocation:

<code>

AClass().f( 1 ); // <--- It is important that the type is int here!

</code>

But the compiler (VC++ 6.0) says:
error C2668: 'f' : ambiguous call to overloaded function

My question is why? Do I understand C++ implicit type conversion
imcorrectly or M$ makes sbth wrong?

TIA
Your problem is that the compiler can not determine what you mean by "1".
Is that an integer or a short? With floating point it's easier, it defaults
to double unless you add f at the end. I'm not even sure if it would have
trouble trying to determine if it wasn't a char value or not (I may test to
find out).

Your function should work for *non constants* because then it knows the type
it's declared as.

How to solve this? Well, this is a good reason for the rule "no magic
numbers". I don't know if there is a solution you would be happy with using
constants.
Jul 4 '06 #6

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

Similar topics

7
by: ishekara | last post by:
Hi, I am having a class template which is used to convert from one type another. I am having a problem when i use the copy constructor with same type. code. #include "stdio.h" template...
6
by: c1t1z3n | last post by:
hiya, i'm having this weird error on my project. As far as I know "ambiguous call to overloaded function" should only occur when the compiler must choose from several methods, but here i don't think...
1
by: subramanian100in | last post by:
Consider the following program: #include <iostream> using namespace std; void print(char c) { cout << "from print(char c) : " << c << endl; return;
4
by: Noah Roberts | last post by:
I am trying to keep a vector of tuples sorted based on the first member and so for my insert function I am calling std::lower_bound with a bound comparator like the following: ...
4
by: Joseph Turian | last post by:
I have a templated class with the following methods: Vocab(const T& t); Vocab(unsigned uid); However, when T = unsigned, and I call Vocab(unsigned(0)) then the compiler rightly complains about...
3
by: valoh | last post by:
Hi, is this legal c++ code? template <typename BaseTstruct A { BaseT& this_() { return *static_cast<BaseT*>(this); } template <typename Tvoid Foo() { this_().Bar<T>(); } template...
1
by: Ruki | last post by:
I want to overload function to swap two others types, for example, type<T>, T* and so on, but I can't compile the following code at VC 6.0. The compiler says : error C2667: 'swap' : none of 2...
8
by: Anna Smidt | last post by:
lf.lfHeight = - (int) (fabs (pt.y) / 10.0 + 0.5) ; Error 1 error C2668: 'fabs' : ambiguous call to overloaded function ezfont.cpp 47 stasm I first thought that the compiler wants to...
32
by: Anna Smidt | last post by:
I am having an "ambiguous call to overloaded function" error again. This is the function: int nGetProfWidth (int ncols, unsigned ProfSpec) { if ((ProfSpec & PROF_2d) == 0) return ncols;...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.