void f(const string& a,const string& b){
// works
int lena = a.length();
int lenb = b.length();
return abs(lena-lenb);
// does not work
return abs(a.length()-b.length());
}
I'm in a little confusion I'm not able call string length() function in abs() function. When I put the result of string length() function in an integer data type there is no error.
The error is this when I call string length() function inside abs().
error: call of overloaded
abs(std::__cxx11::basic_string<char>::size_type) is ambiguous
abs(a.length()-b.length);
When you write:
a.length()-b.length()
The result ends up having type std::size_t because the return type of std::string::length() is std::size_t too.
When you call std::abs with such a type, the compiler has to choose one of the following overloads:
int abs(int n);
long abs(long n);
long long abs(long long n);
std::intmax_t abs(std::intmax_t n);
And there is no rule in the language that promotes/converts an unsigned integer to a specific signed one here, which means the compiler cannot choose for you.
However, when you call it with:
lena-lenb
That has type int since it is the subtraction of two ints, so the following overload is chosen:
int abs(int n);
bool potezn(int x,int y,int k,char c,char ram1[][100],bool segfault,int n,int m)
{
segfault=true;
if(c=='U' && x>=k){x=x-k;segfault=false;}
if(c=='D' && x+k<n){x=x+k;segfault=false;}
if(c=='L' && y>=k){y=y-k;segfault=false;}
if(c=='R' && y+k<m){y=y+k;segfault=false;}
if(ram1[x][y]=='.')ram1[x][y]='N';//zauzima polozaj ukoliko moze
return segfault;
}
segfault=potezn(x,y,q,c,ram,segfault,n,m);
This is my code,and when i run it,i keep getting error
D:\dev\Dev-Cpp\segfault2.cpp
cannot convert char (*)[((unsigned int)((int)m))] to char (*)[100] for argument 5 to bool potezn(int, int, int, char, char (*)[100], bool, int, int)
Help please,
Thanks in advance
The reason you are getting that compile error is because the type of ram that you are trying to call the function potezn with is not the type potezn wants.
Take a careful look at ram.
Its type must be char*[100], not char(*)[((unsigned int)((int)m)]].
You can either declare ram's length explicitly, or change char ram1[][100] to char * ram1. (Also consider using std::vector. std::vector is an array that manages its length automatically for you.)
void Foo(char ram[][100]);
void Bar(char * ram); // Treat the ram as one long chunk array.
int main()
{
char ram[5][100];
char ram_error[5][5];
Foo(ram); // Ok.
Foo(ram_error); // Error.
Bar(reinterpret_cast<char *>(ram_error)); // Ok. Not recommended.
return 0;
}
void qsort (void* base, size_t num, size_t size,
int (*compare)(const void*,const void*));
Why does the qsort function want an int* return type for compare when the compare function is of type int?
int compare (const void * a, const void * b)
{
if ( *(MyType*)a < *(MyType*)b ) return -1;
if ( *(MyType*)a == *(MyType*)b ) return 0;
if ( *(MyType*)a > *(MyType*)b ) return 1;
}
Can someone explain this please, my program wont compile because of this. Thanks!
Code taken from this source:
http://www.cplusplus.com/reference/cstdlib/qsort/
It is not returning an int *, it is returning an int. compare is a function pointer. The * you are seeing there defines it as a function pointer. (Note the parentheses around *compare.)
cdecl parse of int (*compare)(const void*,const void*)):
declare compare as pointer to function (pointer to const void, pointer to const void) returning int
This would be the parameter declaration if it were a pointer to a function returning an int *:
int * (*compare)(const void*,const void*))
If your code is not compiling then it is for some other reason. Consider adding the error message to your question (or creating a new question) if you would like more specific advice about the compiler error.
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
The return type is void* and proto_type is the name of the function? Or is this a pointer to function? Which are the parameters:
(long int, char *b) or this (const char *b, unsigned short int d)
Please, explain how this function works.
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
This is a function declaration. The function name is proto_type, which takes two parameters of types:
long int
char *
and returns a pointer to a function which takes
const char*
unsigned short int
and returns void*.
Now if you use typedef, all of the above will becomes obvious:
typedef void* function_type(const char *b, unsigned short int d);
function_type* proto_type(long int, char *b);
Hope that helps.
This declares proto_type as function taking (long int, char *) and returning pointer to a function taking a (const char *, unsigned short int) and returning a void pointer.
In other words:
typedef void * (*R)(const char *, unsigned short int); // return type
R proto_type(long int, char *);
I suggest bookmarking www.cdecl.org for the questions of this type. Beware, the page is a bit picky about what you type in (it doesn't accept parameter names at least).
Start with the name of the function, then evaluate that using
the usual expression syntax. Thus:
proto_type // proto_type
proto_type( long, char* ) // is a function taking long, char*
// (since function call has precedence over *
*proto_type( long, char* ) // returning a pointer
(*proto_type(...)) // (no change, but necessary for precedence reasons)
(...)( char const*, unsigned short )
// to a function taking char const*, unsigned short
*(...)(...) // returning pointer
void *(...)(...) // to void
(It's a little harder in cases where you don't have the name,
like the type in a static_cast.)
I will explain my process for parsing complex c-style declarations. I hope you will find it useful.
C-style parsing can be thought of as a right-to-left parsing starting at the identifier and bounded by parenthesis. So we start at the identifier proto_type
// vvvvvvvvvv-------------------
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
As we can see, moving right from proto_type, we immediately see a function call and some parameters, so that's easy. proto_type is a function that takes a long int and char* as parameters.
// v
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
Here we hit the first bounding parentheses, so we have to go backwards to find the next token which is here:
// v----------------------------
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
So now we know it returns a pointer to something. Now we have to look to the right again to find out what because of the bounding parentheses again
// v--------------------------------vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
Since we found another function call operator, the pointer it returns must be a pointer to a function that takes a const char* and an unsigned short int.
Finally, we reached another bounding parentheses, so move back left to find the return value of that function pointer.
//vvvv----------------------------------------------------------------------v
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
The function pointer returns a void* as the return value.
So to recap in English: proto_type takes a long int and a char* as parameters and returns a pointer to a function that takes a const char* and unsigned short int as parameters and returns a void*.
proto_type is a function, which takes two arguments, long int and char *. It returns a function pointer that takes two arguments of type const char * and unsigned short int.
And to write this without using typedef is not very kind to the reader.
Using VS2012 on Windows 8 x64.
proto_type is a function that takes a long int (which is unnamed) and an unsigned short int d, and returns a function of the form void * proto2(const char *b, unsigned short int d);
Here's some working code:
#include <stddef.h>
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
void * proto2(const char *b, unsigned short int d);
int main(int argc, char** argv){
if(proto_type(0, NULL)(NULL, 0) != (void*)8675309)
return 0;
else
return 1;
}
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d){
return &proto2;
}
void* proto2(const char *b, unsigned short int d){
return (void*)8675309;
}
What's going on is that main calls proto_type which returns a pointer to proto2, which main immediately calls. proto2 returns a magic pointer value that we check against in main.
Here's the debug output from VS2012:
The program '[3188] test.exe' has exited with code 1 (0x1).
As for "how this function works", the answer is however you want it to (assuming you're the one implementing it).
If you want another way to look at it, you want to read it inside to out for the order of which functions are called.
The lesson here is that C(++) function pointers are immensely opaque.
I have done what #Tomek said and copied your prototype to http:www.cdel.org and then removed the parameter names from the prototype as:
void * (*proto_type(long int, char *)) (const char *, unsigned short int );
pressed enter, and the web site returned:
declare proto_type as function (long int, pointer to char) returning pointer
to function (pointer to const char, unsigned short int) returning pointer
to void
Now, to translate this into carbon-unit speak: proto_type is declared as a function that takes a long int and a pointer to a char as parameters, it returns a pointer to a function that takes a pointer to a const char and an unsigned short integer and that function returns a void pointer.
Finally, a void pointer can be cast into a pointer to any other data type.
I'm using a template to convert integral types into a string representation of their binary values. I used the following:
template<typename T>
std::string ToBinary(const T& value)
{
const std::bitset<std::numeric_limits<T>::digits + 1> bs(value);
const std::string s(bs.to_string());
return s;
}
It works for int but doesn't compile with unsigned int :
unsigned int buffer_u[10];
int buffer_i[10];
...
ToBinary(buffer_i[1]); //compile and works
ToBinary(buffer_u[1]); //doesn't compile -- ambiguous overload
Could you explain why?
EDIT:
Yes, I'm using VS2010
Not your ToBinary call is ambiguous, its the constructor call of bitset with an unsigned value. Unfortunately this is a VC++ Bug: http://connect.microsoft.com/VisualStudio/feedback/details/532897/problems-constructing-a-bitset-from-an-unsigned-long-in-the-vc-rc
Edit - Workaround:
template<>
std::string ToBinary<unsigned int>(const unsigned int& value)
{
const std::bitset<std::numeric_limits<unsigned int>::digits> bs(static_cast<unsigned long long>(value));
return bs.to_string();
}
If you look at the standard (FDIS n3290), then you see that std::bitset has multiple constructors:
First there is this one:
20.5.1 bitset constructors [bitset.cons]
constexpr bitset(unsigned long long val) noexcept;
Effects: Constructs an object of class bitset, initializing the
first M bit positions to the corresponding bit values in val. M is the
smaller of N and the number of bits in the value representation (3.9)
of unsigned long long. If M < N, the remaining bit positions are
initialized to zero.
Then there is also this one, which I suspect might be might cause things to become ambigious, when you call it with unsigned int
template <class charT>
explicit bitset(
const charT* str,
typename basic_string<charT>::size_type n = basic_string<charT>::npos,
charT zero = charT(’0’), charT one = charT(’1’));
Effects: Constructs an object of class bitset as if by
bitset( n == basic_string<charT>::npos ? basic_string<charT>(str) :
basic_string<charT>(str, n), 0, n, zero, one)
Are you using VC10? There is already an issue reported: Microsoft connect. Also I'd guess that you might be able to fix it by casting the type to int if it is 32 bit, like this:
string s = ToBinary(*reinterpret_cast<int*>(&buffer_u[1]));
This can be done inside of the method as well if needed. The result of the reinterpret should not be used for arithmetics anymore, though. ;)
Works fine as workaround for me (but looks quite ugly)
template<typename T>
std::string ToBinary(const T& value)
{
switch (sizeof(T))
{
case 8:
return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const long*>(&value)).to_string();
case 4:
return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const int*>(&value)).to_string();
case 2:
return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const short*>(&value)).to_string();
case 1:
return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const char*>(&value)).to_string();
}
return "n/a";
}