472,958 Members | 2,673 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Ambiguous overload problem

To start off, I'm using GCC4. Specifically, the MingW (setjmp/longjmp) build of GCC 4.2.1 on Windows XP x64.

I'm writing a class that abstracts a message, which can be either an integer (stored as long long int), a decimal (double), or a string (std::string). I basically want to overload most of a Message's operators so that the Message class feels more like a native type. For example...

Expand|Select|Wrap|Line Numbers
  1. Message msg = "tester";
  2. std::string str = msg;
  3. cout << str << "\n"; // would print "tester"
  4.  
  5. msg = 3.14159;
  6. float dec = msg + 2;
  7. cout << dec << "\n"; // would print "5.14159"
...should ideally all work. It mostly does, except this code...

Expand|Select|Wrap|Line Numbers
  1. // part of class Message
  2.  
  3. // either all of these have to be commented out...
  4. //operator char () const { return (char)this->val_integer; };
  5. //operator unsigned char () const { return (unsigned char)this->val_integer; };
  6. operator short int () const { return (short int)this->val_integer; };
  7. operator unsigned short int () const { return (unsigned short int)this->val_integer; };
  8. operator int () const { return (int)this->val_integer; }
  9. operator unsigned int () const { return (unsigned int)this->val_integer; }
  10. operator long int () const { return (long int)this->val_integer; };
  11. operator unsigned long int () const { return (unsigned long int)this->val_integer; };
  12. operator long long int () const { return (long long int)this->val_integer; };
  13. operator unsigned long long int () const { return (unsigned long long int)this->val_integer; };
  14.  
  15. operator float () const { return (float)this->val_decimal; }
  16. operator double () const { return (double)this->val_decimal; }
  17.  
  18. // ...or this has to be commented out, in order for any of it to work
  19. operator const char * () const { return (const char *)this->val_string.c_str(); }; // the 'const char *' matches exactly to one of std::basic_string's operator= handlers
Here, I'm controlling what happens when an instance of Message is used in an expression as a variable. That is, lines 2 and 6 in my usage example at the top are handled by this block of code.

Simply put, the problem is that I cannot handle strings if i'm also handling ints/floats at the same time, else it's telling me it's an ambiguous overload.

std::basic_string<T> defines the following three operator= overloads:
const std::basic_string<T, ..., ...> &
const T*
T

And I have tried to add a handler for each of them. Eg, "operator const std::basic_string<char> & ()" and "operator const char * ()" and "operator char ()". Alone, any of those works as I intend, but as soon as I also try to overload something else, it becomes ambiguous.

It makes sense that my char () handler and my const char * () handler will cause ambiguity, since std::basic_string is overloaded to handle both explicitly, but even if I comment my char handlers out it's still telling me that it's ambiguous. In fact, unless I comment everything but the const char * handler out, it tells me it's ambiguous. Even my double handler alone conflicts with std::basic_string's char handler. Should std::basic_string's operator=(char) overload be able to catch ints and floats like it is? Can I force the overload resolver to pick exact matches if they exists? I've looked over the GCC compile-time flags, and it doesn't appear that I can.

If I'm not making any sense, try taking this into a compiler to see what I mean:

Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <string>
  3.  
  4. class Message {
  5.     public:
  6.     operator const char * () const { return "Pi."; }
  7.     operator double () const { return 3.14159; }
  8. };
  9.  
  10. int main() {
  11.     Message msg;
  12.     std::string temp;
  13.     temp = msg;
  14.     std::cout << temp;
  15.     return 0;
  16. }
In GCC, it's telling me that message can be converted into two types that basic_string will support: one for "const char *" (which is an exact match, and what I want), and one for "char" (apparently it thinks that my double overload is a good match for basic_string's char handler).
Mar 13 '08 #1
3 5667
gpraghuram
1,275 Expert 1GB
i think you cant overload by differentiating the return types as for overloading the parameter types, number of parameters are taken into account.

Raghuram
Mar 13 '08 #2
I'm not overloading return types so much as defining what happens when I cast the instance of Message to another datatype.

Something to add to my original post- if I explicitly cast msg to const char *, it compiles. But for consistency and code length I would like to not have to do that.
Mar 13 '08 #3
weaknessforcats
9,208 Expert Mod 8TB
Your problem is the casting.

Generally, in C++ you cast a) to call relic C functions with arguments like void* or b) your C++ desing is screwed up.

You should a)remove every conversion operator function and then b) design a proper class hierarchy that implements your requirements,
Mar 13 '08 #4

Sign in to post your reply or Sign up for a free account.

Similar topics

1
by: Alan Johnson | last post by:
Consider the following code, with the interesting lines numbered in comments: class A { public : bool f(int level = 1) // line 5 { return true ; }
7
by: glen | last post by:
Hi. I'm using GCC 4.1.1, which I mention since I don't know if this is a compiler issue, or me not understanding some subtlety in the standard. The code below compiles fine under vc++, but I'm...
2
by: Tim H | last post by:
Why is this ambiguous: ------------------------------------------------ #include <boost/shared_ptr.hpp> class base {}; class derived: public base {}; class other {}; void...
9
by: neildferguson | last post by:
I am using templates with a little project I am working on. My compiler (GCC) is finding a particular construct ambiguous. Can anyone suggest something I might change in the declaration of class...
11
by: onkar | last post by:
#include<iostream> using namespace std; class Integer{ int i; public: Integer(int ii):i(ii){} const Integer operator+(const Integer& rv){ cout<<"1-operator+"<<endl; return Integer(i+rv.i); }
9
by: sebastian | last post by:
I've simplified the situation quite a bit, but essentially I have something like this: struct foo { }; void bar( foo const & lhs, foo const & rhs )
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: Nikola | last post by:
Hello, I'm writing a String class for C++ and I'm getting the following error message when using operator: test.cpp: In function ‘int main()’: test.cpp:7: error: ISO C++ says that these are...
3
by: mathieu | last post by:
Could someone please tell me what is wrong with the following -ugly- piece of c++ code. Why when I explicititely set the template parameter my gcc compiler start getting confused: bla.cxx: In...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
2
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

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.