code review on .cpp and .h. Wont compile

My goal is to create a function that has one parameter and returns an integer value. There are several possible parameters; If the parameter is a double it will return an 1, if it is an integer it will return a 2, if it is a long integer it will return a 3 etc. (there are more types of parameters but I dont need to list them.

My problem is that when i attempt to compile I get the following errors attached to both the header and the cpp file
error C2668: 'dataType' : ambiguous call to overloaded function
datatype.h(7): could be 'int dataType(long)'
datatype.h(6): or 'int dataType(unsigned long)'
datatype.h(5): or 'int dataType(float)'
datatype.h(4): or 'int dataType(double)'
datatype.h(3): or 'int dataType(long double)'
while trying to match the argument list '(int)'

I've googled my error and spent the last 3 days trying to work on this. Would appreciate any help. I'm at my wits end

here is the header file (dataType.h)
1
2
3
4
5
6
7
#define dataType_h

int dataType(long double dataIn);
int dataType(double dataIn);
int dataType(float dataIn);
int dataType(unsigned long dataIn);
int dataType(long dataIn);


and here is the .cpp file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include "c:\users\veemoney\csc263\dataType.h"
using namespace::std;

int (A);		
int rtn;	

int main()
{
	rtn = dataType(A);
	cout << rtn << "\n";
	return rtn;
};

int dataType(long double dataIn)
{
	rtn = dataType(1);
	cout << rtn << "\n";
	return rtn;
};

int dataType(double dataIn)
{
//	rtn dataType
	cout << rtn << "\n";
	return rtn;
};

The reason that you get an ambiguity is because the compiler can't tell whether it should call the long double version or the double version. If you call it with an int, the "weakness" or prioritization of both conversions is equal, which leads to an ambiguous call. I'd suggest just one type, double.

EXTENDED CLARIFICATION:
When a function is overloaded, the compiler examines every call to the function. If a given call's arg list perfectly matches an existing overload, that overload is called. Otherwise, the compiler determines what conversions would be necessary to perform each call. If one conversion is ranked as being better than the other (for less loss of data, etc), the compiler will choose the best overload, but ONLY IF THERE IS ONE. If there are multiple "ideal" conversions, the call is ambiguous and the compiler cannot perform it, being unable to choose the right function to call.
Because the int > long double and int > double casts are just about the same (seeing as no data would be lost in almost any normal case), the compiler cannot decide which one to call. This ambiguity prevents you from calling the function. You must therefore design an overloaded function to avoid ambiguities. By providing a variant of the function for every floating point type there is, you almost guarantee an ambiguity unless you call the function with a floating point type. Such behavior is, generally, bad design and should be avoided. One floating point and one integer should really be sufficient.
You may think that the problem should be resolved because you have long versions of dataType but that's not the case because you never define them. So the compiler overlooks them.
By the way, you should NOT have semicolons at the end of curly brackets. The sole exception is the do {} while, to my knowledge.
Last edited on
also note your not using your parameters "dataIn". This may be intentional as you haven't finished coding yet. but things like

1
2
3
4
5
6
7
8
9
10
int dataType(long double dataIn)   // your not using "dataIn"
{
	rtn = dataType(1);
	cout << rtn << "\n";
	return rtn;
}; // you also don't need semi-colons after every function/member
// these are typically only needed for header declaration;

int dataType(double dataIn)   // your not using "dataIn"


edit: to clarify: on a header declaration:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef MYHEADER_H
#define MYHEADER_H

#include <iostream> // etc

class MyClass
{
   public:
      MyClass();
      ~MyClass();
      SomeOther();
      DoIt();
   private:
      int myAge;
      std::string myName;
};   // <--- semi-colon needed here

#endif 


TBH, I don't think it matters too much as the compiler simply removes all white space and semicolons and the like when compiling, but really they are just not necessary except in the above example.
Last edited on
Topic archived. No new replies allowed.