I started learning about templates and I copied the code from my book but the compiler is giving me this error
Error 1 error: 'swap' : ambiguous call to overloaded function"
Here is my program
#include <iostream>
template <typename X>
void swap(X &a, X &b);
int _tmain(){
using namespace std;
int a, b;
cout << "enter two numbers:\n";
cin >> a >> b;
cout << "Your numbers are: " << a << ", " << b << endl;
swap(a, b); //error is here
cout << "Your numbers reversed are: " << a << ", " << b << endl;
return 0;
}
template <typename X>
void swap(X &a, X &b){
X temp = a;
a = b;
b = temp;
}
You are redefining the function swap with the same signature, so you're having an ambiguous definition of it, and, consequently, an ambiguous call.
If you want to maintain the function with the same signature, you should either choose to use not the "using namespace std;", which will not shadow your swap() definition, or simply define tthe function in another namespace.
Example:
namespace your_namespace {
template <typename X>
void swap(X &a, X &b) {
X temp = a;
a = b;
b = temp;
}
}
int foo(10), bar(20);
std::cout << "foo: " << foo << "; bar: " << bar << std::endl;
your_namespace::swap(foo, bar);
std::cout << "foo: " << foo << "; bar: " << bar << std::endl;
Output:
foo: 10; bar: 20
foo: 20; bar: 10
Regards!
Related
If static variables has only one copy for the program. So why is it not possible to swap 2 numbers using another function?
Code:
#include <iostream>
void swap(int, int);
int main()
{
static int a = 1;
static int b = 2;
swap(a, b);
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
std::cin.get();
}
void swap(int a,int b)
{
int temp = a;
a = b;
b = temp;
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
}
As the 'swap' function is taking parameters as pass by value, copies of the variables are passed to the swap function which will only swap its local variables 'a' and 'b' (passed as parameter) not the static ones passed from main.
Swap should be taking parameters as references like below.
#include <iostream>
void swap(int&, int&);
int main()
{
static int a = 1;
static int b = 2;
swap(a, b);
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
std::cin.get();
}
void swap(int &a,int &b)
{
int temp = a;
a = b;
b = temp;
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
}
Please note that static variable defined in a function pertains its value in the subsequent calls of the function in which it is declared.
This is because you are passing arguments by value and not by address(reference). Your function is working on a copy of a and a copy of b - not the original values. You could try this(notice the & in the function prototype and function definition arguments)
void swap(int &, int &);
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
}
I have a case where lookup and overload resolution behaves differently:
for user-defined class vs built-in types vs std::string
for direct call vs function pointer call
I cannot figure what exact parts of the standard justify these differences.
Consider the following C++11 code:
#include <iostream>
#include <string>
using namespace std;
struct Test1 {};
struct Test2 {};
template<typename T>
int f(T t) { return 0; }
int f(Test1 t) { return 10; }
int f(int y) { return 20; }
template<typename T>
int use1() { return f(T()); }
template<typename T>
int use2() { auto fp = static_cast<int(*)(T)>(&f); return (*fp)(T()); }
int f(Test2 t) { return 30; }
int f(string s) { return 40; }
int f(double y) { return 50; }
int main() {
cout << "use1<float>: " << use1<float>() << endl;
cout << "use1<Test1>: " << use1<Test1>() << endl;
cout << "use1<int>: " << use1<int>() << endl;
cout << "use1<Test2>: " << use1<Test2>() << endl;
cout << "use1<string>: " << use1<string>() << endl;
cout << "use1<double>: " << use1<double>() << endl;
cout << endl;
cout << "use2<float>: " << use2<float>() << endl;
cout << "use2<Test1>: " << use2<Test1>() << endl;
cout << "use2<int>: " << use2<int>() << endl;
cout << "use2<Test2>: " << use2<Test2>() << endl;
cout << "use2<string>: " << use2<string>() << endl;
cout << "use2<double>: " << use2<double>() << endl;
return 0;
}
Output is (same with g++ 6.3 and clang++5.0.0 trunk):
use1<float>: 0
use1<Test1>: 10
use1<int>: 20
use1<Test2>: 30
use1<string>: 0
use1<double>: 0
use2<float>: 0
use2<Test1>: 10
use2<int>: 20
use2<Test2>: 0
use2<string>: 0
use2<double>: 0
Questions:
Why use1<string> is different from use1<Test2> ? Both types are declared "at the top", both f() overloads are declared at the bottom.
Why use1<Test2> is different from use1<double>? Corresponding f() overloads are on adjacent lines, is there anything special in treatment of built-in types?
Why use1<Test2> is different from use2<Test2>? The type of a pointer to function in use2 seems to match the calling context in use1.
Two-phase name lookup. At the point where use1 is defined, three overloads of f are visible via normal lookup. At the point of instantiation, additional overloads may be found - but only by argument-dependent lookup. Test2 is in global namespace, so f(Test2) is found by ADL; whereas string is in namespace std, and so f(string) (which is, obviously, not in namespace std) is not found by ADL. double has no associated namespaces, and so ADL doesn't kick in at all.
In use2, f is not a dependent name, and so the second-phase lookup is not performed at all - only overloads visible at the point of definition are considered.
I cannot understand the order of constructor and destructor calls? What will execute first in this statement A b=f(a)? Can someone please help me out?
#include<iostream>
using namespace std;
class A {
int x;
public:
A(int val = 0)
:x(val) {
cout << "A " << x << endl << flush;
}
A(const A& a) {
x = a.x;
cout << "B " << x << endl << flush;
}
void SetX(int x) {
this->x = x;
}
~A() {
cout << "D " << x << endl << flush;
}
};
A f(A a) {
cout << " C " << endl << flush;
a.SetX(100);
return a;
}
int main()
{
A a(1);
A b=f(a);
b.SetX(-100);
return 0;
}
Output Window:
A 1
B 1
C
B 100
D 100
D -100
D 1
Why does it print B 1 in line 2 of the output window?
"Why does it print B 1 in line 2?"
Because the copy constructor was called from this statement
A b=f(a);
The function f() requires A being passed by value, thus a copy for this parameter is made on the function call stack.
If your next question should be, how you can get over this behavior, and avoid to call the copy constructor, you can simply pass the A instance as a reference to f():
A& f(A& a) {
// ^ ^
cout << " C " << endl << flush;
a.SetX(100);
return a;
}
Side note: endl << flush; is redundant BTW, std::endl includes flushing already.
I have two template classes that inherits from each other. And I have a struct Date that I want to pass into a function in one of the classes but I get this error when I compile:
no operator found which takes a right-hand operand of type 'Date' (or there is no acceptable conversion)
The error is in line 95 specifically.
As you can see in my code, I am passing different data types to test if the function works. All of them worked perfectly except struct Date.
What am I doing wrong?
my code:
#include <iostream>
#include <string>
using namespace std;
template <typename T> class B; //forward declare
template <typename T>
class A
{
T valuea;
public:
A(){};
T getValuea()
{
return valuea;
}
void setValuea(T x)
{
valuea = x;
}
A(const A &x)
{
valuea = x.valuea;
}
friend class B<T>; //A<int> is a friend of B<int>
};
template <typename T>
class B : A<T>
{
T valueb;
public:
using A<T>::setValuea;
using A<T>::getValuea;
B(){};
T getValueb()
{
return valueb;
}
void setValueb(T x)
{
valueb = x;
}
B(const B &x)
{
valueb = x.valueb;
this->valuea = x.valuea;
}
};
struct Date
{
int day;
int month;
int year;
};
int main()
{
B<float> b;
b.setValuea(1.34);
b.setValueb(3.14);
cout << "b.setValuea(1.34): " << b.getValuea() << endl
<< "b.setValueb(3.14): " << b.getValueb() << endl;
B<int> a;
a.setValuea(1);
a.setValueb(3);
cout << "a.setValuea(1): " << a.getValuea() << endl
<< "a.setValueb(3): " << a.getValueb() << endl;
B<char> y;
y.setValuea('a');
y.setValueb('c');
cout << "y.setValuea('a'): " << y.getValuea() << endl
<< "y.setValueb('c'): " << y.getValueb() << endl;
B<string> u;
u.setValuea("good");
u.setValueb("morning");
cout << "u.setValuea(good): " << u.getValuea() << endl
<< "u.setValueb(morning): " << u.getValueb() << endl;
B<Date> p;
p.setValuea({ 27, 10, 2014 });
p.setValueb({ 2, 11, 2014 });
cout << "p.setValuea({ 27, 10, 2014 }): " << p.getValuea() << endl
<< "p.setValueb({ 2, 11, 2014 }): " << p.getValueb() << endl;
system("Pause");
return 0;
}
You need to provide an operator<< for your Date class, otherwise it doesn't know how to output it to a stream. You could try the following:
struct Date
{
int day;
int month;
int year;
friend ostream& operator << (ostream& os, const Date& date)
{
return os << "Day: " << date.day << ", Month: " << date.month << ", Year: " << date.year << " ";
}
};
Live example: http://ideone.com/ehio6Q
I have written a function template and an explicitly specialized templated function which simply takes in 3 arguments and calculates the biggest among them and prints it.
The specialized function is causing an error,whereas the template works fine.
But I want to work with char* type.
This is the error I get=>
error: template-id ‘Max<>’ for ‘void Max(char, char, char)’ does not match any template declaration
Following is my code:
template <typename T>
void Max(T& a,T& b,T& c)
{
if(a > b && a >> c)
{
cout << "Max: " << a << endl;
}
else if(b > c && b > a)
{
cout << "Max: " << b << endl;
}
else
{
cout << "Max: " << c << endl;
}
}
template <>
void Max(char* a,char* b,char* c)
{
if(strcmp(a,b) > 0 )
{
cout << "Max: " << a << endl;
}
else if(strcmp(b,c) > 0)
{
cout << "Max: " << b << endl;
}
else
{
cout << "Max: " << b << endl;
}
}
You need to take the pointers by reference:
template <>
void Max(char*& a,char*& b,char*& c)
That said, it would be better not to use an explicit specialization and instead just overload the function:
void Max(char* a, char* b, char* c)
It's almost always a bad idea to specialize function templates. For more, see Herb Sutter's "Why Not Specialize Function Templates?"
I ran into the same problem and fixed it by using typedef:
typedef char * charPtr;
template <>
void Max(charPtr &a, charPtr &b, charPtr &c)