Can anyone tell me the cause of error ?
Error is
C:\web\template1.cpp||In function 'int main()':|
C:\web\template1.cpp|23|error: call of overloaded 'swap(int&, int&)' is ambiguous|
C:\web\template1.cpp|6|note: candidates are: void swap(X&, X&) [with X = int]|
c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\bits\move.h|76|note: void std::swap(_Tp&, _Tp&) [with _Tp = int]|
C:\web\template1.cpp|24|error: call of overloaded 'swap(double&, double&)' is ambiguous|
C:\web\template1.cpp|6|note: candidates are: void swap(X&, X&) [with X = double]|
c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\bits\move.h|76|note: void std::swap(_Tp&, _Tp&) [with _Tp = double]|
C:\web\template1.cpp|25|error: call of overloaded 'swap(char&, char&)' is ambiguous|
C:\web\template1.cpp|6|note: candidates are: void swap(X&, X&) [with X = char]|
c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\bits\move.h|76|note: void std::swap(_Tp&, _Tp&) [with _Tp = char]|
||=== Build finished: 3 errors, 0 warnings ===|
#include <iostream>
using namespace std;
template <typename X>
void swap(X &a, X &b)
{
X temp = a;
a = b;
b = temp;
}
int main()
{
int i=10, j=20;
double x=10.1, y=23.3;
char a='x', b='z';
cout<<"i="<<i<<"\tj="<<j<<endl;
cout<<"x="<<x<<"\ty="<<y<<endl;
cout<<"a="<<a<<"\tb="<<b<<endl;
swap(i,j);
swap(x,y);
swap(a,b);
cout<<"i="<<i<<"\tj="<<j<<endl;
cout<<"x="<<x<<"\ty="<<y<<endl;
cout<<"a="<<a<<"\tb="<<b<<endl;
return 0;
}
Your swap conflicts with std::swap. Remove using namespace std; above and correct the rest code from std namespace.
std::cout<<"i="<<i<<"\tj="<<j<<std::endl;
std::cout<<"x="<<x<<"\ty="<<y<<std::endl;
std::cout<<"a="<<a<<"\tb="<<b<<std::endl;
Also it's worth reading Why is "using namespace std" considered bad practice?
Rename swap() as swap2() or the like. Or, better, never issue using namespace std;.
As written, your code introduces std::swap() through iostream, then dumps it atop your own swap() by using namespace.
There is already a swap function declared somewhere in your code. Change the function's name or remove the declaration of the other swap function.
This ambiguous errors occur due to using std functions as general functions.
There are two ways to overcome this.
1) Instead of declaring using namespace std; use std::cout
whenever you need to print any and std::endl for new line.
#include <iostream>
template <typename X>
void swap(X &a, X &b)
{
X temp = a;
a = b;
b = temp;
}
int main()
{
int i=10, j=20;
double x=10.1, y=23.3;
char a='x', b='z';
std::cout<<"i="<<i<<"\tj="<<j<<std::endl;
std::cout<<"x="<<x<<"\ty="<<y<<std::endl;
std::cout<<"a="<<a<<"\tb="<<b<<std::endl;
swap(i,j);
swap(x,y);
swap(a,b);
std::cout<<"i="<<i<<"\tj="<<j<<std::endl;
std::cout<<"x="<<x<<"\ty="<<y<<std::endl;
std::cout<<"a="<<a<<"\tb="<<b<<std::endl;
return 0;
}
2) You can also change the swap to Swap to not conflict with the inbuilt std::swap function.
#include <iostream>
using namespace std;
template <typename X>
void Swap(X &a, X &b)
{
X temp = a;
a = b;
b = temp;
}
int main()
{
int i=10, j=20;
double x=10.1, y=23.3;
char a='x', b='z';
cout<<"i="<<i<<"\tj="<<j<<endl;
cout<<"x="<<x<<"\ty="<<y<<endl;
cout<<"a="<<a<<"\tb="<<b<<endl;
Swap(i,j);
Swap(x,y);
Swap(a,b);
cout<<"i="<<i<<"\tj="<<j<<endl;
cout<<"x="<<x<<"\ty="<<y<<endl;
cout<<"a="<<a<<"\tb="<<b<<endl;
return 0;
}
Related
I'm using a template function, which the goal is reciever a vector and a function, and return the function type.
template <typename T, typename Function>
auto apply(const std::vector<T>& V, const Function &F){
vector<Function> x; # ERROR HERE
return x;
}
But the IDE give me error (http://coliru.stacked-crooked.com/a/ee6ce2127e013a18):
/usr/local/include/c++/10.2.0/ext/new_allocator.h: In instantiation of 'class __gnu_cxx::new_allocator<double(double)>':
/usr/local/include/c++/10.2.0/bits/allocator.h:116:11: required from 'class std::allocator<double(double)>'
/usr/local/include/c++/10.2.0/bits/stl_vector.h:87:21: required from 'struct std::_Vector_base<double(double), std::allocator<double(double)> >'
/usr/local/include/c++/10.2.0/bits/stl_vector.h:389:11: required from 'class std::vector<double(double), std::allocator<double(double)> >'
main.cpp:10:22: required from 'auto apply(const std::vector<T>&, const Function&) [with T = int; Function = double(double)]'
main.cpp:19:39: required from here
/usr/local/include/c++/10.2.0/ext/new_allocator.h:96:7: error: 'const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = double(double); __gnu_cxx::new_allocator<_Tp>::const_pointer = double (*)(double); __gnu_cxx::new_allocator<_Tp>::const_reference = double (&)(double)]' cannot be overloaded with '_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = double(double); __gnu_cxx::new_allocator<_Tp>::pointer = double (*)(double); __gnu_cxx::new_allocator<_Tp>::reference = double (&)(double)]'
96 | address(const_reference __x) const _GLIBCXX_NOEXCEPT
| ^~~~~~~
/usr/local/include/c++/10.2.0/ext/new_allocator.h:92:7: note: previous declaration '_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = double(double); __gnu_cxx::new_allocator<_Tp>::pointer = double (*)(double); __gnu_cxx::new_allocator<_Tp>::reference = double (&)(double)]'
92 | address(reference __x) const _GLIBCXX_NOEXCEPT
| ^~~~~~~
main.cpp: In function 'int main(int, char**)':
main.cpp:19:31: error: conversion from 'vector<double(double),allocator<double(double)>>' to non-scalar type 'vector<double,allocator<double>>' requested
19 | vector<double> r = ::apply(v, seno);
| ~~~~~~~^~~~~~~~~
This is call of the main function.
double seno( double n ) { return sin(n); }
int main( int argc, char* argv[]) {
vector<int> v{ 1, 2, 3, 4, 5 };
vector<double> r = ::apply(v, seno);
cout << r;
return 0;
}
I don't know what I'm doing wrong, so How can I improve this method and pass trough this error?
EDIT: The purpse to generalize the in method insted of using double in the vector is because I want o re-use in another way. So I've generalize the most that I can.
vector<Function> x; // ERROR HERE defines a vector of function pointers. But that's not what you want - you want a vector of the return type of the function. And that's what decltype() is for.
In your apply function, F is the function to be called and T is the type of the values in the vector being passed in. That means T() is the default value of the items in the vector (in this case the default value of int is 0). Then, F(T()) would actually call the function with 0 and return something so decltype(F(T())) tells you the type of the thing returned.
That means you need to write vector<decltype(F(T()))> x; instead.
T() works because the type is int and it is default constructible. As #alterigel said in the comments std::declval<T>() is better when the type is not default constructible.
So vector<decltype(F(std::declval<T>()))> x; might be needed in some situations.
The whole program would look like:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
template <typename T, typename Function>
auto apply(const std::vector<T>& V, const Function &F) {
vector<decltype(F(T()))> x;
for(auto a : V)
x.push_back(F(a));
return x;
}
double seno( double n ) { return sin(n); }
int main( int argc, char* argv[]) {
vector<int> v{ 1, 2, 3, 4, 5 };
vector<double> r = ::apply(v, seno);
for (auto a : r)
cout << a << " ";
return 0;
}
Try it here: https://onlinegdb.com/SknTsVaHO
I am trying to understand std::bind(). I am trying to understand the code in the post https://riptutorial.com/cplusplus/example/7541/std--function-used-with-std--bind.
Code is as below.
#include <iostream>
#include <functional>
using namespace std;
class A
{
public:
std::function<void(int, const std::string&)> m_CbFunc = nullptr;
void foo()
{
if (m_CbFunc)
{
m_CbFunc(100, "event fired");
}
}
};
class B
{
public:
B(int x) : y(x)
{
auto aFunc = std::bind(&B::eventHandler, this, std::placeholders::_1, std::placeholders::_2);
anObjA.m_CbFunc = aFunc;
}
void eventHandler(int i, const std::string& s)
{
std::cout << s << ": " << i << std::endl;
}
void DoSomethingOnA()
{
anObjA.foo();
}
int y;
A anObjA;
};
int main(int argc, char *argv[])
{
B anObjB(4);
anObjB.DoSomethingOnA();
}
I couldn't understand why we are using this in bind call
auto aFunc = std::bind(&B::eventHandler, this, std::placeholders::_1, std::placeholders::_2)
eventHandler is taking 2 parameters and we are binding with placeholders. Not sure why do we need to pass this. If I remove this, I am getting below error.
/usr/include/c++/6/functional:1286:7: error: static assertion failed: Wrong number of arguments for pointer-to-member
static_assert(_Varargs::value
^~~~~~~~~~~~~
main.cpp: In constructor ‘B::B(int)’:
main.cpp:34:27: error: no match for ‘operator=’ (operand types are ‘std::function&)>’ and ‘std::_Bind&)>(std::_Placeholder<1>, std::_Placeholder<2>)>’)
anObjA.m_CbFunc = aFunc;
^~~~~
In file included from main.cpp:10:0:
/usr/include/c++/6/functional:1929:7: note: candidate: std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {int, const std::basic_string, std::allocator >&}]
operator=(const function& __x)
^~~~~~~~
The this is needed because eventHandler() is not a static method. std::bind() is used specifically when you want to use non-static methods of your class.
Note that personally, I find it ugly and don't like using it. I use lambdas instead.
anObjA.m_CbFunc = [=](int i, const std::string&s) { eventHandler(i,s); };
Even though the syntax for lambdas is kind of ugly, I don't think it's as ugly or obscure as bind. But that's just my preference.
I'm trying to map string to function pointer, so that I can call the function with iter->second(arg) instead of if-else.
I have written a simple one without class, and it works as expected.
But when I modify it as below, it shows compile errors.
#include <functional>
#include <iostream>
#include <unordered_map>
#include <string>
using std::string;
class A{
private:
int a(int num, string s) { return s.size() + num; }
int b(int num, string s) { return num - s.size(); }
public:
void ido(string str){
typedef std::function<int(int, string)> process_func;
std::unordered_map<string, process_func> m;
m.insert(std::make_pair<string, process_func>("a", &A::a));
// using std::placeholders::_1;
// m.insert(std::make_pair<string, process_func>("a", std::bind(&A::a, this, _1)));
// m["a"] = std::bind(&A::a, this, _1);
// m.insert({{"a", &A::a}, {"b", &A::b}});
auto x = m.find(str);
if(x == m.end()) {
std::cout << "Not supported!" << std::endl;
}
std::cout << x->second(10, "hello") << std::endl;
}
};
int main(int argc, char* argv[]) {
A a;
a.ido(string(argv[1]));
return 0;
}
The errors are:
function.cc: In member function ‘void A::ido(std::string)’:
function.cc:17:65: error: no matching function for call to ‘make_pair(const char [2], int (A::*)(int, std::string))’
m.insert(std::make_pair<string, process_func>("a", &A::a));
^
function.cc:17:65: note: candidate is:
In file included from /usr/include/c++/4.8.2/utility:70:0,
from /usr/include/c++/4.8.2/tuple:38,
from /usr/include/c++/4.8.2/functional:55,
from function.cc:1:
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
make_pair(_T1&& __x, _T2&& __y)
^
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5: note: template argument deduction/substitution failed:
function.cc:17:65: note: cannot convert ‘&A::a’ (type ‘int (A::*)(int, std::string) {aka int (A::*)(int, std::basic_string<char>)}’) to type ‘std::function<int(int, std::basic_string<char>)>&&’
m.insert(std::make_pair<string, process_func>("a", &A::a));
What does the error mean? How to fix it?
While your functions 'a' and 'b' do not depend on 'this' (they do not access anything inside class A), the compiler is not smart enough to deduce this. So the error means that you are trying to convert 'pointer to method' to 'pointer to function', which is incorrect conversion. 'Pointer to method' requires and object to be called on. You need to declare methods 'a' and 'b' as 'static' to indicate that they are actually standalone functions, not methods of the class.
I can't figure out what is ambiguous about swap(arr[i++],arr[n--]); below. Please educate me on my wrongful ways.
#include <iostream>
#include <string>
template <typename T> void swap ( T & a, T & b )
{
T temp = b;
b = a;
a = temp;
}
template <typename T> void reverse_array ( T * arr, size_t n )
{
size_t i = 0;
while (i < n) swap(arr[i++],arr[n--]); // problem line
}
int main ()
{
char mystr [] = "Obama smokes";
reverse_array(mystr, sizeof(mystr)/sizeof(char));
return 0;
}
codepad has an implicit using namespace std;, which is a really bad idea and makes your swap conflict with std::swap. You can use ::swap instead, but not before fixing your bounds problem by passing sizeof mystr - 2 instead of sizeof(mystr)/sizeof(char).
As #minitech mentions in his answer, the problem is because of the implicit namespace declaration, e.g. using namespace std;
With that I get the following error, which shows that the conflict is with std::swap:
100%] Building CXX object CMakeFiles/csi_projects.dir/main.cpp.o
/home/vsnyc/ClionProjects/main.cpp: In instantiation of ‘void reverse_array(T*, size_t) [with T = char; size_t = long unsigned int]’:
/home/vsnyc/ClionProjects/main.cpp:151:52: required from here
/home/vsnyc/ClionProjects/main.cpp:144:43: error: call of overloaded ‘swap(char&, char&)’ is ambiguous
while (i < n) { swap(arr[i++],arr[n--]); } // problem line
^
/home/vsnyc/ClionProjects/main.cpp:144:43: note: candidates are:
/home/vsnyc/ClionProjects/main.cpp:134:28: note: void swap(T&, T&) [with T = char]
template <typename T> void swap ( T & a, T & b )
^
In file included from /usr/include/c++/4.8/bits/stl_pair.h:59:0,
from /usr/include/c++/4.8/bits/stl_algobase.h:64,
from /usr/include/c++/4.8/bits/char_traits.h:39,
from /usr/include/c++/4.8/ios:40,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from /home/vsnyc/ClionProjects/main.cpp:1:
/usr/include/c++/4.8/bits/move.h:166:5: note: void std::swap(_Tp&, _Tp&) [with _Tp = char]
swap(_Tp& __a, _Tp& __b)
^
#include <iostream>
using namespace std;
template<typename T>
T max(T lhs, T rhs)
{
return lhs < rhs ? rhs : lhs;
}
template<>
int max<int>(int lhs, int rhs)
{
return lhs < rhs ? rhs : lhs;
}
int main()
{
cout << max<int>(4, 5) << endl;
}
~/Documents/C++/boost $ g++ -o testSTL testSTL.cpp -Wall
testSTL.cpp: In function ‘int main()’:
testSTL.cpp:18:24: error: call of overloaded ‘max(int, int)’ is ambiguous
testSTL.cpp:11:5: note: candidates are: T max(T, T) [with T = int]
/usr/include/c++/4.5/bits/stl_algobase.h:209:5: note: const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int]
How do I correct this error?
It's all because of your using namespace std;. Remove that line.
By that using-directive, you bring std::max (which must be somehow included via iostream) into the global scope. Therefore the compiler doesn't know which max to call - ::max or std::max.
I hope this example will be a good scarecrow for those who think that using directives come at no cost. Weird errors are one side effect.
I guess the compiler can't work out whether to use std::max or your max, because you've got a using namespace std; and both your max and the std::max fit the bill
You're colliding with std::max(). Rename it to something else like mymax and it will work.
You have both your max and std::max. The compiler doesn't know which one you intended to call.
You can tell it by calling ::max(4,5) or std::max(4,5), or - even better - not have using namespace std in the file.
That's because there's already std::max template function defined.
Remove the 'using namespace std' and add 'std::' where needed., or use '::max'.
The problem is that there is already a function named 'max' defined by std. To fix this, rename your function to something else, like this:
#include <iostream>
using namespace std;
template<typename T>
T mymax(T lhs, T rhs)
{
return lhs < rhs ? rhs : lhs;
}
template<>
int mymax<int>(int lhs, int rhs)
{
return lhs < rhs ? rhs : lhs;
}
int main()
{
cout << mymax<int>(4, 5) << endl;
return 0;
}