Consider the following:
int foo(int x , int z = 0);
int foo(int x, int y , int z = 0);
If I call this function like so:
foo( 1 , 2);
How does the compiler know which one to use?
It won't and hence this example will not compile cleanly, it will give you an compilation error.
It will give you an ambiguous function call error.
Online Sample:
int foo(int x , int z = 0){return 0;}
int foo(int x, int y , int z = 0){return 10;}
int main()
{
foo( 1 , 2);
return 0;
}
Output:
prog.cpp: In function ‘int main()’:
prog.cpp:6: error: call of overloaded ‘foo(int, int)’ is ambiguous
prog.cpp:1: note: candidates are: int foo(int, int)
prog.cpp:2: note: int foo(int, int, int)
It doesn't, that's why you get a compiler error.
That is a nice question. But it will not compile because of ambigious call to foo(). You can remove this ambiguity by using different datatypes in function signature.
For more detail about default parameter and function overloading see http://www.smart2help.com/e-books/ticpp-2nd-ed-vol-one/Chapter07.html
Compiler will report Ambiguous function overload. As you cannot figure out which function will b called so does the compiler
Related
#include <vector>
#include <thread>
int main()
{
vector<int> a;
thread s(&vector<int>::push_back,&a,3);
}
I get compile error for these code:
main.cpp:52:39: error: no matching function for call to
‘std::thread::thread(<unresolved overloaded function type>, std::vector<int>*, int)’
thread s(&vector<int>::push_back,&a,3);
can I get any help?
The error is telling you that it doesn't know which overload of vector<int>::push_back to use,
void vector<int>::push_back(const int& val);
or
void vector<int>::push_back(int&& val);
since they both have the same name.
The solution is to static_cast to the required function type, or declare a variable of the correct type,
e.g.
thread s(static_cast<void(vector<int>::*)(const int&)>(&vector<int>::push_back),&a,3);
or
void (vector<int>::* func)(const int&) = &vector<int>::push_back;
thread s(func, &a, 3);
I know, it's horribly ugly.
You can try passing a lambda:
thread s([](vector<int>& a, int b) {
a.push_back(b);
}, std::ref(a), 3);
I would think this should work:
#include "boost/serialization/strong_typedef.hpp"
BOOST_STRONG_TYPEDEF(int, StrongInt);
int main()
{
StrongInt len (100);
int *heapInts = new int [len];
}
gcc 4.8.2:
./StrongTypeTest.cpp: In function ‘int main()’:
./StrongTypeTest.cpp:8:30: error: ambiguous default type conversion from ‘StrongInt’
int *heapInts = new int [len];
^
./StrongTypeTest.cpp:8:30: error: candidate conversions include ‘StrongInt::operator const int&() const’ and ‘StrongInt::operator int&()’
Here is a busybox I wrote to play with the new feature in gcc-4.8.1+ (I think clang-2.9+ should do this too) for N2439 (ref-qualifiers for 'this'):
class Foo
{
public:
Foo(int i) : _M_i(i) { }
int bar() & { return _M_i /= 2; }
int bar() const & { return _M_i; }
int bar() && { return 2 * _M_i; }
private:
int _M_i = 42;
};
int
main()
{
Foo ph(333);
ph.bar();
const Foo ff(123);
ff.bar();
Foo(333).bar();
}
It looks to me reading the standard 8.3.5 that the three bar() methods should be overloadable. I get a linker error though:
[ed#localhost ref_this]$ ../bin/bin/g++ -std=c++11 -o ref_this ref_this.cpp
/tmp/ccwPhzqr.s: Assembler messages:
/tmp/ccwPhzqr.s:73: Error: symbol `_ZN3Foo3barEv' is already defined
If I comment out int bar() const & I am unable to resolve ff.bar();:
[ed#localhost ref_this]$ ../bin/bin/g++ -std=c++11 -o ref_this ref_this.cpp
ref_this.cpp: In function ‘int main()’:
ref_this.cpp:26:10: error: no matching function for call to ‘Foo::bar() const’
ff.bar();
^
ref_this.cpp:26:10: note: candidates are:
ref_this.cpp:11:7: note: int Foo::bar() &
int bar() & { return _M_i /= 2; }
^
ref_this.cpp:11:7: note: no known conversion for implicit ‘this’ parameter from ‘const Foo’ to ‘Foo&’
ref_this.cpp:13:7: note: int Foo::bar() &&
int bar() && { return 2 * _M_i; }
^
ref_this.cpp:13:7: note: no known conversion for implicit ‘this’ parameter from ‘const Foo’ to ‘Foo&&’
Is this a gcc bug or part of the standard?
I'm not on my computer with clang on it but what does clang say?
This feature is not supported by GCC up to version 4.8.0. It should be supported by GCC 4.8.1, which has not been officially released yet.
To the best of my knowledge, the only major compiler that supports reference qualifiers on member functions at the moment is Clang. As you can see from this example, your code compiles fine on Clang 3.2.
I want to create a function prototype in C++ so that there is a void * argument that can take pointers of any type. I know that this is possible in C. Is it possible in C++?
[EDIT] Here is a simplified version of the code that I am trying to get to work:
#include <stdio.h>
void func(void (f)(const void *))
{
int i = 3;
(*f)(&i);
}
void func_i(const int *i)
{
printf("i=%p\n",i);
}
void func_f(const float *f)
{
printf("f=%p\n",f);
}
void bar()
{
func(func_i);
}
And here is the compiler output:
$ g++ -c -Wall x.cpp
x.cpp: In function ‘void bar()’:
x.cpp:21: error: invalid conversion from ‘void (*)(const int*)’ to ‘void (*)(const void*)’
x.cpp:21: error: initializing argument 1 of ‘void func(void (*)(const void*))’
$ %
You may use void*, just as with C, but you'll need to cast your argument when calling it. I suggest you use a template function
template<typename T>
void doSomething(T* t) {...}
Yes.
int i = 345;
void * ptr = &i;
int k = *static_cast< int* >(ptr);
UPDATE ::
What you have shown in the code certainly cannot be done in C++.
Casting between void and any other must always be explicitly done.
Check these SO link for more details on what the C -standard has to say:
1) http://stackoverflow.com/questions/188839/function-pointer-cast-to-different-signature
2) http://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type
How about:
void func(void *);
exactly like in C? : P
Take the following C/C++ code:
#include <stdlib.h>
int inc(int i) { return i+1; } // int→int, like abs()
// baz is bool→(int→int)
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
int (*foo(bool))(int); // foo is &(bool→(int→int))
foo = baz;
}
Attempting to compile this (gcc or g++) gives:
$ g++ test.cc
test.cc: In function ‘int main()’:
test.cc:9: error: assignment of function ‘int (* foo(bool))(int)’
test.cc:9: error: cannot convert ‘int (*(bool))(int)’ to ‘int (*(bool))(int)’ in assignment
Check for yourself: the two types it claims it cannot convert between are exactly the same. Why then is it claiming that they are incompatible?
EDIT 1: The problem disappears when using typedefs (as is recommended), like so:
int main() {
typedef int (*int2int)(int);
typedef int2int (*bool2_int2int)(bool);
bool2_int2int foo;
foo = baz;
}
EDIT 2: The compiler, of course, was right. The problem with my original code, as many pointed out, is that foo in main() is a declaration of a function, and not a function pointer. The error in the assignment was therefore not conflicting types but assigning to a function, which is not possible. The correct code is:
#include <stdlib.h>
int inc(int i) { return i+1; } // int→int, like abs()
// baz is bool→(int→int)
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
int (*(*foo)(bool))(int); // foo is &(bool→(int→int))
foo = &baz;
}
The code is in fact wrong. The problem is that this line:
int (*foo(bool))(int); // foo is &(bool→(int→int))
... doesn't mean what you think it means. It's interpreted as a declaration of a function named "foo". That makes perfect sense. Think about it - if you had wanted to forward declare "baz", you would have put int (*baz(bool))(int); , right? Also, since baz is a function which returns a function pointer, and foo is a pointer to a function which returns a function pointer, wouldn't you expect the syntax to be more complicated?
You declared foo as a function of the same type as baz, rather than as a pointer to a function of same type as baz.
From your compiler, the first error message is the useful one - it tells you assignment of function, i.e. you have tried to assign to a function, which is an error.
I'm not even going to try to write the correct solution without typedefs :-) Here's some code which compiles and I think is right, using typedefs:
#include <stdlib.h>
#include <stdbool.h>
typedef int(*IntReturnsInt)(int);
int inc(int i) { return i+1; }
IntReturnsInt baz(bool b) { return b ? &abs : &inc; }
int main() {
IntReturnsInt (*foo)(bool b);
foo = baz;
}
In this example the double-function-pointer concept is a bit clearer - IntReturnsInt is a function pointer type and foo is a pointer to a function which returns IntReturnsInt... phew :-)
This is a function declaration.
int (*foo(bool))(int);
If you wanted to declare a function pointer, you should do:
int (*(*foo)(bool))(int);
It's difficult to be sure, but I think this is closer to the OP's intent:
// baz is a function returning a pointer to a function
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
// foo is a pointer to a function
int (*foo)(int) ;
foo = baz(true); // Now foo is equal to &abs
}
you cannot assign to function type (int (*foo(bool))(int);), you need to use pointer to function
int (*(*foo)(bool))(int);
foo = &baz;
#include <stdlib.h>
#include <stdbool.h>
int inc(int i) { return i+1; } // int→int, like abs()
// baz is bool→(int→int)
int (*baz(bool b))(int) { return b ? &abs : &inc; }
int main() {
int (*(*foo)(bool))(int); // foo is &(bool→(int→int))
foo = baz;
return 0;
}
So there were a few side-issues clouding the core issue. Your "bool" was being interpreted as a default-int untyped parameter because the actual built-in is _Bool, humanized by the previously-missing #include <stdbool.h>. The lack of a pointer declaration for the object on the stack was confounding its ability to conform to the type of the real function object in static memory just above.
Once I included <stdbool.h>, the error shifted to "lvalue required" complaint, because there was only a function declaration and not a pointer object. The code above will compile with no warnings or errors.