472,371 Members | 1,645 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,371 software developers and data experts.

Overloading operators using templates...

I was wondering if someone could help me get around this problem I'm
having. I'm writing a fraction class and would like to overload the
binary arithmetic operators so that when any numerical data type (int,
double, long double, etc.) is used with a fraction it is first
converted to a fraction and then added, the result being a fraction.

So I started with this:

template <class numericType>
friend fraction operator +(const fraction& lhs, const numericType&
rhs);
template <>
friend fraction operator +(const fraction& lhs, const fraction& rhs);

The first function was simply:

{ return lhs + fraction(rhs); }

The second function was a template specialization that did the math
when adding two fractions. This worked great, as long as a fraction
was the first argument I could add it with any other data type that I
had a constructor for. But I also want addition to be commutative so
that "fraction + int" and "int + fraction" do the same thing. To get
that I added this function:

template <class numericType>
friend fraction operator +(const numericType& lhs, const fraction&
rhs);

Which did the same thing as the other function, converted explicitly to
a fraction and then added, relying on the template specialization to
add fractions. But now I get this error:

error C2667: '+' : none of 2 overload have a best conversion

How can I get rid of this? I just want it so that given:
fraction x, y;
int z;

these statements are valid and error free:

x + y;
x + z;
z + x;

I'm running VC++ 6.0

Jul 23 '05 #1
3 2357
Starx wrote:
I was wondering if someone could help me get around this problem I'm
having. I'm writing a fraction class and would like to overload the
binary arithmetic operators so that when any numerical data type (int,
double, long double, etc.) is used with a fraction it is first
converted to a fraction and then added, the result being a fraction.

So I started with this:

template <class numericType>
friend fraction operator +(const fraction& lhs, const numericType&
rhs);
template <>
friend fraction operator +(const fraction& lhs, const fraction& rhs);

The first function was simply:

{ return lhs + fraction(rhs); }

The second function was a template specialization that did the math
when adding two fractions. This worked great, as long as a fraction
was the first argument I could add it with any other data type that I
had a constructor for. But I also want addition to be commutative so
that "fraction + int" and "int + fraction" do the same thing. To get
that I added this function:

template <class numericType>
friend fraction operator +(const numericType& lhs, const fraction&
rhs);

Which did the same thing as the other function, converted explicitly to
a fraction and then added, relying on the template specialization to
add fractions. But now I get this error:

error C2667: '+' : none of 2 overload have a best conversion

How can I get rid of this? I just want it so that given:
fraction x, y;
int z;

these statements are valid and error free:

x + y;
x + z;
z + x;

I'm running VC++ 6.0


If class 'fraction' has constructors for each of the
required numeric types (fraction(int), fraction(long),
fraction(double), etc), then you should only need one
friend operator+() method that takes 2 'fraction'
objects. If a numeric is specified on either side
of the "+" (z + x, or x + z), the compiler should
apply the correct conversion constructor before
invoking the operator+().

Here's an example:

#include <iostream>

// a dummy 'fraction' class for experimental purposes
class fraction
{
public:
fraction() : vd(0) {}
fraction(const int v) : vd(v) {}
fraction(const long v) : vd(v) {}
fraction(const double v) : vd(v) {}

fraction operator=(const fraction& oth)
{ vd = oth.vd; vi = oth.vi; }

friend fraction operator+(const fraction& rhs, const fraction& lhs);

int vi;
double vd;
};
fraction operator+(const fraction& rhs, const fraction& lhs)
{ return fraction(rhs.vd + lhs.vd); }

int main()
{
fraction fx(25.34), fy(30), fr;
int iz = 66;
long lz = 530;

std::cout << "fx = " << fx.vd << ", "
<< "fy = " << fy.vd << ", "
<< "iz = " << iz << ", "
<< "lz = " << lz << std::endl;

fr = fx + fy;
std::cout << "fx + fy = " << fr.vd << std::endl;

fr = fx + iz; // 'iz' is converted to a 'fraction'
std::cout << "fx + iz = " << fr.vd << std::endl;

fr = iz + fx; // 'iz' is converted to a 'fraction'
std::cout << "iz + fx = " << fr.vd << std::endl;

fr = lz + fx; // 'lz' is converted to a 'fraction'
std::cout << "lz + fx = " << fr.vd << std::endl;

fr = 99 + fy; // 99 is converted to a fraction
std::cout << "99 + fy = " << fr.vd << std::endl;

fr = fy + 99; // 99 is converted to a fraction
std::cout << "fy + 99 = " << fr.vd << std::endl;

return 0;
}

Regards,
Larry
Jul 23 '05 #2
Larry I Smith wrote:
[snip]

If class 'fraction' has constructors for each of the
required numeric types (fraction(int), fraction(long),
fraction(double), etc), then you should only need one
friend operator+() method that takes 2 'fraction'
objects. If a numeric is specified on either side
of the "+" (z + x, or x + z), the compiler should
apply the correct conversion constructor before
invoking the operator+().

[snip]

Don't forget to include constructors for any required
unsigned types, e.g.: fraction(unsigned int), etc.

Larry
Jul 23 '05 #3
My constructor is flagged with the explicit keyword. I did this
because I was also trying to overload the pow function. I wanted to
write different versions for fraction and int powers to optimize the
way it did the math, but if I don't make the constructor explicit it
says those version are ambiguous.

Jul 23 '05 #4

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

Similar topics

4
by: Dave Theese | last post by:
Hello all, I'm trying to get a grasp of the difference between specializing a function template and overloading it. The example below has a primary template, a specialization and an overload. ...
2
by: Marcin Vorbrodt | last post by:
I see a lot of source code where some operators are defined as class members, and some as friends, or just outside the class. Can someone please explain what the general rule of thumb is? I...
2
by: bq | last post by:
Hello, This post is really two questions. Question 1: What is the current status on a revision of ISO C++, specifically regarding plans for overloading composite operators? Some people in this...
20
by: KL | last post by:
I am working on a school assignment, so please don't tell me the solution. I just want some direction. I am supposed to overload the >, <, ==, !=, >=, and <= operators using bool. I am having...
6
by: TuxC0d3 | last post by:
Hi! I'm diving into the some more ++ specific aspects of c++ (and finally accepting that c++ is more than "a plus added to c" :), so that means using namespaces, templates, std::strings, lists,...
2
by: allan.mcrae | last post by:
I am having trouble with overloading the += operator when template parameters are used. I have a class holding an array (called "derived" in the following example) which derives from a base class...
11
by: Zilla | last post by:
I have the following simple program. I just want to be able to do math operations (+, -, =)on Timer sublcasses, but want to handle cases where either rhs or lhs is an intrinsic value, However, the...
8
by: Wayne Shu | last post by:
Hi everyone, I am reading B.S. 's TC++PL (special edition). When I read chapter 11 Operator Overloading, I have two questions. 1. In subsection 11.2.2 paragraph 1, B.S. wrote "In particular,...
30
by: none | last post by:
I'm trying to overload the = operator using templates, but I have some problems with one of the overloads, I would like to make something like that: intvariable = fooclass; here's a pseudo...
2
by: jimzat | last post by:
I am trying to simulate the execution of some PLC ladder logic in python. I manually modified the rungs and executed this within python as a proof of concept, but I'd like to be able to skip the...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
1
by: Johno34 | last post by:
I have this click event on my form. It speaks to a Datasheet Subform Private Sub Command260_Click() Dim r As DAO.Recordset Set r = Form_frmABCD.Form.RecordsetClone r.MoveFirst Do If...
1
by: ezappsrUS | last post by:
Hi, I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...
0
by: jack2019x | last post by:
hello, Is there code or static lib for hook swapchain present? I wanna hook dxgi swapchain present for dx11 and dx9.
0
DizelArs
by: DizelArs | last post by:
Hi all) Faced with a problem, element.click() event doesn't work in Safari browser. Tried various tricks like emulating touch event through a function: let clickEvent = new Event('click', {...

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.