Why is there an ambiguous call for templatized function? - c++

I have a problem with creating a template in c++. I am using xcode for mac.
When passing an int to a swap function I get the error code "ambiguous call". However, passing strings works fine. Why is that?
This is my code
#include <iostream>
#include <cmath>
using namespace std;
template <typename T>
void swap(T& c, T& d)
{
T temp = c;
c = d;
d = temp;
}
int main()
{
int a = 10;
int b = 20;
swap(a, b); // this is an error "ambiguous call"
cout << a << "\t" << b;
string first_name = "Bob";
string last_name = "Hoskins";
swap(first_name, last_name); // this works
cout << first_name << "\t" << last_name;
return 0;
}

You have using namespace std; which brings std::swap into scope. This means the template swap that you have written conflicts with std::swap, and you get an ambiguous call when you pass it 2 ints.
Takeaway: Never do using namespace std;
The interesting part is that calling swap with 2 std::strings works. That's because there is a specialization of std::swap for std::string. The specialization is considered a better match, and so it's called instead of your own swap.

Related

Why is this C++ code which uses decltype and remove_reference with the goal of getting the value type of a pointer working unexpectedly

When I run the snippet below, it prints out:
int&
int __cdecl(void)
I was expecting the second line to just be int
Why is this happening? What could I do to fix it if it were inside a templated function that takes pointers or iterators so I couldn't use std::remove_pointer.
#include <type_traits>
#include <iostream>
int main()
{
int r = 4;
int* rp = &r;
using return_type = decltype(*rp);
using no_ref_type = std::remove_reference<return_type>::type();
std::cout << typeid(return_type).name() << '&' << std::endl;
std::cout << typeid(no_ref_type).name();
}

C++ header issue involving functions and scope

My problem is in the following C++ code. On the line with the 'cout' I get the error:
"'number' was not declared in this scope".
.h
using namespace std;
class a{
int number();
};
.cpp
using namespace std;
#include <iostream>
#include "header.h"
int main(){
cout << "Your number is: " << number() << endl;
return 0;
}
number(){
int x = 1;
return x;
}
Note: I'm aware this isn't the cleanest code. I just wanted to get the function working and refresh my memory on how to use headers.
For minimal fix, three basic changes are necessary.
Proper implementation of the number() method
int a::number() {
int x = 1;
return x;
}
Proper invocation of the number() method
a aObject;
cout << "Your number is: " << aObject.number() << endl;
There are many other enhancements possible though.
Addition, as pointed out by #CPlusPlus, usable scope of number() method, for example declaring it public
class a{
public:
int number();
};
Try this in your cpp file
using namespace std;
#include <iostream>
#include "header.h"
void a::number()
{
int x = 1;
return x;
}
int main()
{
cout << "Your number is: " << a().number() << endl;
return 0;
}
As for your header file replace class with a struct. The reason you are getting this error is because the compiler cant find the variable number. It is actually a method of a class.The reason you are replacing the class with a struct is because by default everything in a struct is public. So your header file called header.h should look like this
using namespace std;
struct a
{
int number();
};
There are three issues with your code.
The definition of the function number().
As you declared, it is a member function of the class "a". In your .cpp, the class name should be used as a prefix to the function. I mean,
a::number(){
int x = 1;
return x;
}
As the function is a member of the class "a", there are only two ways of accessing it,
If the function is a static function in the class, you can access it with :: operator. Like a::number().
If the function is not a static function, that is true in your case, you should instantiate the object out of the class "a" and they use "." operator with the reference. I mean,
a obj;
obj.number().
Your function number() is declared in private scope. You may recall that by default the scope is a class is private unless you specify public or protected. So the private function number() cannot be used outside the declared class unless there is a friend to it.
Below the code that I fixed,
.h
using namespace std;
class a{
public:
int number();
};
.cpp
using namespace std;
#include <iostream>
#include "header.h"
a::number(){
int x = 1;
return x;
}
int main(){
a obj;
cout << "Your number is: " << obj.number() << endl;
return 0;
}

C++ templates facing overload mismatch issue. What is wrong in the code?

#include <iostream>
using namespace std;
template<class T>
inline void swap(T &i,T &j)
{
T temp = i;
i=j;
j=temp;
}
int main ()
{
int a = 2,b =5;
swap(a,b);
cout << "a=" <<a<< " b=" <<b<<endl;
return 0;
}
This is a simple swap program using templates. I am new to templates and wanted to learn how to use it.
using namespace std is the problem. There is an std::swap() function that is causing the function call to become ambiguous.

C++ Function Pointer as Argument

I have tried multiple google searches and help guides, but I'm out of ideas on this one. I have a function pointer that I am using as an argument for another function. Both functions are within the same class. However, I keep getting type conversion errors. I'm sure this is just a syntax problem, but I can't understand what the correct syntax is. Here is a simplified version of my code:
Header File
#ifndef T_H
#define T_H
#include <iostream>
#include <complex>
namespace test
{
class T
{
public:
T();
double Sum(std::complex<double> (*arg1)(void), int from, int to);
int i;
std::complex<double> func();
void run();
};
}
#endif // T_H
Source File
#include "t.h"
using namespace test;
using namespace std;
//-----------------------------------------------------------------------
T::T()
{
}
//-----------------------------------------------------------------------
double T::Sum(complex<double>(*arg1)(void), int from, int to)
{
complex<double> out(0,0);
for (i = from; i <= to; i++)
{
out += arg1();
cout << "i = " << i << ", out = " << out.real() << endl;
}
return out.real();
}
//-----------------------------------------------------------------------
std::complex<double> T::func(){
complex<double> out(i,0);
return out;
}
//-----------------------------------------------------------------------
void T::run()
{
Sum(&test::T::func, 0, 10);
}
Whenever I try to compile, I get the following error:
no matching function for call to 'test::T::Sum(std::complex<double> (test::T::*)(),int,int)'
note: no known conversion for argument 1 from 'std::complex<double> (test::T::*)()' to 'std::complex<double>(*)()'
Any advice appreciated. Or at least a link to a thorough site on how to use function pointers. I am using Qt Creator 2.6.2, compiling with GCC.
Your Sum function expects pointer to a function. And then you try to call it with a pointer to a member function. Learn about pointers to members.
The code itself is a bit messy, I'll only correct the grammer to make it work.
firstly, you shall change the function prototype from
double Sum(std::complex<double> (*arg1)(void), int from, int to);
to
double Sum(std::complex<double> (T::*arg1)(void), int from, int to);
Meaning that it is a pointer to class T's member.
Then, when calling the function, you cant just arg1(),
for (i = from; i <= to; i++)
{
out += arg1();
cout << "i = " << i << ", out = " << out.real() << endl;
}
you have to use (this->*arg1)();
for (i = from; i <= to; i++)
{
out += (this->*arg1)();
cout << "i = " << i << ", out = " << out.real() << endl;
}
How to pass functions as arguments in C++? In general, use a template, unless you have very compelling reasons not do it.
template<typename Func>
void f(Func func) {
func(); // call
}
On the call side, you can now throw in a certain amount of objects (not just pointers to functions):
Functors;
struct MyFunc {
void operator()() const {
// do stuff
}
};
// use:
f(MyFunc());
Plain functions:
void foo() {}
// use
f(&foo) {}
Member functions:
struct X {
void foo() {}
};
// call foo on x
#include <functional>
X x;
func(std::bind(&X::foo, x));
Lambdas:
func([](){});
If you really want a compiled function and not a template, use std::function:
void ff(std::function<void(void)> func) {
func();
}

Using binder1st with custom functor

I'd like to bind the first argument of my print functor to 0:
#include<iostream>
#include<functional>
using namespace std;
class Print : public std::binary_function<int,int,void>{
public:
void operator()(int val1, int val2)
{
cout << val1 + val2 << endl;
}
};
int main()
{
Print print;
binder1st(print,0) f; //this is line 16
f(3); //should print 3
}
The program above (based on an example from C++ Primer Plus) does not compile:
line16 : error : missing template arguments before ‘(’ token
What is wrong?
I don't want to use C++11 nor boost features.
Edited: operator() return type has been changed from bool to void for simplicity
As the error message says, you are missing template arguments before the (
This is what you want
std::binder1st<Print> f(print, 0);
However, you also need to make your operator() const as follows
bool operator()(int val1, int val2) const
Finally, this function needs to return something.
binder1st needs template-arguments, try
binder1st<Print> f(print, 0);
See the reference here.
Example
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
int main () {
binder1st < equal_to<int> > equal_to_10 (equal_to<int>(),10);
int numbers[] = {10,20,30,40,50,10};
int cx;
cx = count_if (numbers,numbers+6,equal_to_10);
cout << "There are " << cx << " elements equal to 10.\n";
return 0;
}
std::binder1st is a class template, so it needs a template parameter.
binder1st<Print> f(print,0);
// ^^^^^^^
But if you really want to bind the second argument, then you need to use the aptly named std::binder2nd.