Ambiguous Overloaded Functions - How and Why? - c++

I'm having serious trouble figuring out what is making certain function calls ambiguous and others are fine. I have the following overloaded function calls within my BitPacker object:
static __declspec(dllexport) void PackBits(void *dstBuffer, unsigned long long data, unsigned int &offsetBits, const unsigned int numBits);
static __declspec(dllexport) void PackBits(void *dstBuffer, bool data, unsigned int &offsetBits, const unsigned int numBits);
static __declspec(dllexport) void PackBits(void *dstBuffer, float data, unsigned int &offsetBits, const unsigned int numBits);
static __declspec(dllexport) void PackBits(void *dstBuffer, double data, unsigned int &offsetBits, const unsigned int numBits);
I am trying to make the following call from within another object that is including "BitPacker.h":
void Date::ReflectToBitBuffer(void)
{
unsigned int offsetBits = 0;
BitPacker::PackBits(m_packedBuffer, m_year, offsetBits, YR_BITS);
BitPacker::PackBits(m_packedBuffer, m_month, offsetBits, MO_BITS);
BitPacker::PackBits(m_packedBuffer, m_day, offsetBits, DY_BITS);
}
"m_year", m_month", and "m_day" are int member variables. However I am getting the following errors when attempting to compile:
error C2668: 'BitPacker::PackBits' : ambiguous call to overloaded function
could be 'void BitPacker::PackBits(void *,double,unsigned int &,const unsigned int)'
or 'void BitPacker::PackBits(void *,float,unsigned int &,const unsigned int)'
or 'void BitPacker::PackBits(void *,bool,unsigned int &,const unsigned int)'
or 'void BitPacker::PackBits(void *,unsigned __int64,unsigned int &,const unsigned int)'
while trying to match the argument list '(char *, int, unsigned int, )'
So I wrote a test solution with the following main.cpp to test out overloads and what I have below compiles fine:
void OverloadTest(float f);
void OverloadTest(int n, int &numbits);
void OverloadTest(double d);
void OverloadTest(char c, int &numbits);
void OverloadTest(long long l, int &numbits);
void OverloadTest(long long *l);
void OverloadTest(bool b);
int main(int argc, int *argv)
{
int myInt = 77;
bool myBool = true;
float myFloat = 3.14159f;
double myDouble = 1.57;
long long myLongLong = 12345;
long long *ptrLongLong = NULL;
char myChar = 'q';
int myNumBits = 10;
OverloadTest(myInt, myNumBits);
OverloadTest(myFloat);
OverloadTest(myDouble);
OverloadTest(myLongLong, myNumBits);
OverloadTest(ptrLongLong);
OverloadTest(myChar, myNumBits);
OverloadTest(myBool);
return 0;
}
void OverloadTest(float _f) { int x = 0; }
void OverloadTest(int _n, int &_numbits) { int x = 0; }
void OverloadTest(double _d) { int x = 0; }
void OverloadTest(char _c, int &_numbits) { int x = 0; }
void OverloadTest(long long _l, int &_numbits) { int x = 0; }
void OverloadTest(long long *_l) { int x = 0; }
void OverloadTest(bool b) { int x = 0; }
I even tried to simplify:
void Date::ReflectToBitBuffer(void)
{
unsigned int offsetBits = 0;
unsigned int testVar2 = 12;
unsigned int testVar1 = 1977;
BitPacker::PackBits(m_packedBuffer, testVar1, offsetBits, testVar2);
}
And I still get the ambiguity. If I use a float however I don't. At the moment I am utterly confused why my test scenario does not produce this error. Would anyone be able to shed some light on what the problem is because the function prototype signatures in the first code example look to me to be different enough to allow it to compile.

It looks like that "int" can be casted into all 4 types of your overloaded function and none of them exactly matches your call. Maybe that's the problem.
Try making your call exactly match the function definiton or making an int version for your call?

Related

C++: Array of external class functions

I am using a library that wants an array of functions, like this:
Original main.cpp:
void test1(OLEDDisplay* display, OLEDDisplayUiState* state, int16_t x, int16_t y) {}
void test2(OLEDDisplay* display, OLEDDisplayUiState* state, int16_t x, int16_t y) {}
void OledDisplay() {
FrameCallback f[] = {test1, test2};
ui.setFrames(f, 2);
}
...and that works well. But I want to place test1 and test2 in a class in another linked file:
ilb.h:
class ILB {
public:
ILB();
void test1(OLEDDisplay*, OLEDDisplayUiState* , int16_t, int16_t);
void test2(OLEDDisplay*, OLEDDisplayUiState* , int16_t, int16_t);
};
ilb.cpp:
...
void ILB::test1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {}
void ILB::test2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {}
...
New main.cpp:
ILB ilb;
void OledDisplay() {
FrameCallback f[] = {ilb.test1, ilb.test2};
ui.setFrames(f, 2);
}
And that gives me this error:
src/main.cpp:35:44: error: cannot convert 'ILB::test1' from type 'void (ILB::)(OLEDDisplay*, OLEDDisplayUiState*, int16_t, int16_t)' {aka 'void (ILB::)(OLEDDisplay*, OLEDDisplayUiState*, short int, short int)'} to type 'FrameCallback' {aka 'void (*)(OLEDDisplay*, OLEDDisplayUiState*, short int, short int)'}
I can't figure out what is missing...

Error obtaining parameters of a structure pointer in c ++

I have defined the following structure:
struct com_NetworkStruct
{
enum com_NetworkStatus status;
char IPV4_Addr[COM_IPV4_ADDR_LENGTH];
char IPV4_Netmask[COM_IPV4_ADDR_LENGTH];
char IPV4_DNS1[COM_IPV4_ADDR_LENGTH];
char IPV4_DNS2[COM_IPV4_ADDR_LENGTH];
int IPV4_DHCP_Enabled;
int IPV6_Supported;
int IPV6_Enabled;
struct com_IPv6_Data *IPV6_Address_List;
char HW_Addr[COM_ETH_MAC_ADDR_LENGTH];
int MTU_Size;
int Link_Speed;
enum com_LinkType Link_Type;
};
And the following method definition:
int foo(struct com_NetworkStruct **netinfo);
This is the main function and how i call the function:
int main(int argc, char const *argv[])
{
int ret;
char data_aux[200];
struct com_NetworkStruct *netinfo = NULL;
ret = foo(&netinfo);
memset(data_aux, 0, sizeof(data_aux));
sprintf(data_aux, "%s", netinfo->IPV4_Addr);
cout<<string(data_aux)<<endl;
return 0;
}
The problem is when I try to read the data of the IPV4_Addr value since it sends me the following error:
Error: #289: no instance of constructor "std::basic_string<_CharT, Traits, Alloc>::basic_string [with CharT=char, Traits=std::char_traits<char>, _Alloc=std::allocator<char>]" matches the argument list
argument types are: (const char [20], char [16])
I already tried this, but nothing works:
&netinfo->IPV4_Addr
netinfo.IPV4_Addr
string(netinfo->IPV4_Addr)

Pass pointer to function works in simple case but not after "class"-ifying

I am a somewhat rusty programmer, and new to C++. I've been asked to write a program that can pass a pointer to a function into another function and execute. I can make the simple case work, where everything is in a .cpp file. But when I place the code in a class inside a .h file it won't compile. I am either code blind or missing something.
Here is the code that works:
/*
* funcptr.cpp
*
* Example:
* - pass function pointer as argument
* - execute passed function
*/
#include <stdio.h>
void takes_a_function(void (*f)(void *data), void *data);
void print_char(void *data);
void print_int(void *data);
// This function gets passed (to takes_a_function)
void print_char(void *data) {
char *ch = (char *)data;
printf("%c\n", *ch);
}
// This function gets passed (to takes_a_function)
void print_int(void *data) {
int *i = (int *)data;
printf("%d\n", *i);
}
void takes_a_function(void (*f)(void *), void *data) {
//f(data); // this also works
(*f)(data);
}
int main() {
int i = 100;
takes_a_function(print_int, &i);
char ch = 'A';
takes_a_function(print_char, &ch);
}
It compiles and runs:
# g++ funcptr.cpp -o funcptr
# ./funcptr
100
A
So far so good. But then I put the code into a .h file and "class"-ify it so I can use it from anywhere, and everything falls apart:
#ifndef __funcptr_h__
#define __funcptr_h__
#include <stdio.h>
void takes_a_function(void (*f)(void *data), void *data);
void print_char(void *data);
void print_int(void *data);
void testit();
class FunctionPtr
{
public:
// This function gets passed (to takes_a_function)
void print_char(void *data) {
char *ch = (char *)data;
printf("%c\n", *ch);
}
// This function gets passed (to takes_a_function)
void print_int(void *data) {
int *i = (int *)data;
printf("%d\n", *i);
}
void takes_a_function(void (*f)(void *a), void *data) {
//f(data); // this also works
(*f)(data);
}
void testit() {
int i = 100;
takes_a_function(print_int, &i);
char ch = 'A';
takes_a_function(print_char, &ch);
}
};
#endif
The compiler error is:
# g++ funcptr.h
funcptr.h: In member function ‘void FunctionPtr::testit()’:
funcptr.h:34:33: error: invalid use of non-static member function ‘void FunctionPtr::print_int(void*)’
takes_a_function(print_int, &i);
^
funcptr.h:22:7: note: declared here
void print_int(void *data) {
^~~~~~~~~
funcptr.h:37:35: error: invalid use of non-static member function ‘void FunctionPtr::print_char(void*)’
takes_a_function(print_char, &ch);
^
funcptr.h:16:7: note: declared here
void print_char(void *data) {
^~~~~~~~~~
I've been playing with this for a while and done a fair amount of reading on passing function pointers, including on StackOverflow, however all the examples I see are simple and of no help.
Any insights are much appreciated.
Thanks to all.
It looks to me like your problem is when you call takes_a_function with your arguments.
You declared the data parameter as a pointer to a void type, not a reference to a void type.
You could try something like:
void testIt() {
int i = 100;
int * j = &i;
takes_a_function(print_int, j);
char c = 'a';
char * d = &c;
takes_a_function(print_char, d);
};
References and pointers are not exactly the same thing.
Also it looks like you forgot a #endif after you define __funtptr_h__
I hope this helped

C++ error C2084: function already has a body

I know this question has been asked before, but it's a clear issue in every other case. Everyone accidentally called their constructor twice. I, on the other hand, am having this issue because of prototypes in a header file, and it makes no damn sense. I'm having the error called on every single function called between these two files. Thanks!
Auto.h
#ifndef AUTO_H
#define AUTO_H
#include<string>
using std::string;
class Auto
{
public:
Auto();
Auto(const char* mk, const char* ml, int d);
void setDoors(int d);
int getDoors(void) const;
const string getMake(void) const;
const string getModel(void) const;
void setMake(const char *mk);
void setModel(const char *ml);
private:
int doors;
string make;
string model;
};
#endif
Auto.cpp
#include "Auto.h"
Auto::Auto()
{
// The strings are constructed empty by their default construtors
doors = 2;
}
Auto::Auto(const char* mk, const char* ml, int d)
{
setMake(mk);
setModel(ml);
setDoors(d);
return;
}
void Auto::setDoors(int d)
{
if (d>0)
doors = d;
else
doors = 2;
return;
}
int Auto::getDoors(void) const
{
return doors;
}
const string Auto::getMake(void) const
{
return make;
}
const string Auto::getModel(void) const
{
return model;
}
void Auto::setMake(const char *mk)
{
if (mk != 0) {
make = mk;
}
return;
}
void Auto::setModel(const char *ml)
{
if (ml != 0) {
model = ml;
}
return;
}
Error messages:
1> Lab11.cpp 1>m:\cosc1030\lab11\lab11\lab11\auto.cpp(14): error C2084: function 'Auto::Auto(void)' already has a body
1> m:\cosc1030\lab11\lab11\lab11\auto.h(18) : see previous definition of '{ctor}' 1>m:\cosc1030\lab11\lab11\lab11\auto.cpp(20): error C2084: function 'Auto::Auto(const char *,const char *,int)' already has a body
1> m:\cosc1030\lab11\lab11\lab11\auto.h(19) : see previous definition of '{ctor}'

How do I store a function to a variable?

I think they are called functors? (it's been a while)
Basically, I want to store a pointer to a function in a variable, so I can specify what function I want to use from the command line.
all the functions return and take the same values.
unsigned int func_1 (unsigned int var1)
unsigned int func_2 (unsigned int var1)
function_pointer = either of the above?
so then I could call it by going: function_pointer(my_variable)?
EDIT:
as per #larsmans's suggestion, I've gotten this:
Config.h:
class Config
{
public:
unsigned static int (*current_hash_function)(unsigned int);
};
Config.cpp:
#include "Config.h"
#include "hashes.h"
unsigned static int (*current_hash_function)(unsigned int) = kennys_hash_16;
hashes.h:
unsigned int kennys_hash(unsigned int out);
unsigned int kennys_hash_16(unsigned int out);
hashes.cpp:
just implements the functions in the header
main.cpp:
#include "Config.h"
#include "hashes.h"
// in test_network:
unsigned int hashed = Config::current_hash_function(output_binary);
//in main():
else if (strcmp(argv[i], "-kennys_hash_16") == 0)
{
Config::current_hash_function = kennys_hash_16;
}
else if (strcmp(argv[i], "-kennys_hash_8") == 0)
{
Config::current_hash_function = kennys_hash;
}
the error I get:
g++ -o hPif src/main.o src/fann_utils.o src/hashes.o src/Config.o -lfann -L/usr/local/lib
Undefined symbols:
"Config::current_hash_function", referenced from:
test_network() in main.o // the place in the code I've selected to show
auto_test_network_with_random_data(unsigned int, unsigned int, unsigned int)in main.o
generate_data(unsigned int, unsigned int, unsigned int)in main.o
_main in main.o // the place in the code I've selected to show
_main in main.o // the place in the code I've selected to show
generate_train_file() in fann_utils.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [hPif] Error 1
The simplest you can do is
unsigned int (*pFunc)(unsigned int) = func_1;
This is a bare function pointer, which cannot be used to point to anything other than a free function.
You can make it less painful if your compiler supports the C++0x auto keyword:
auto pFunc = func_1;
In any case, you can call the function with
unsigned int result = pFunc(100);
There are many other options that provide generality, for example:
You can use boost::function with any C++ compiler
With a compiler implementing features of C++0x you can use std::function
These can be used to point to any entity that can be invoked with the appropriate signature (it's actually objects that implement an operator() that are called functors).
Update (to address updated question)
Your immediate problem is that you attempt to use Config::current_hash_function (which you declare just fine) but fail to define it.
This defines a global static pointer to a function, unrelated to anything in class Config:
unsigned static int (*current_hash_function)(unsigned int) = kennys_hash_16;
This is what you need instead:
unsigned int (*Config::current_hash_function)(unsigned int) = kennys_hash_16;
From C++11 you can use std::function to store functions. To store function you use it as follsonig:
std::function<return type(parameter type(s))>
as an example here it is:
#include <functional>
#include <iostream>
int fact (int a) {
return a > 1 ? fact (a - 1) * n : 1;
}
int pow (int b, int p) {
return p > 1 ? pow (b, p - 1) * b : b;
}
int main (void) {
std::function<int(int)> factorial = fact;
std::function<int(int, int)> power = pow;
// usage
factorial (5);
power (2, 5);
}
No, these are called function pointers.
unsigned int (*fp)(unsigned int) = func_1;
You could also use function either from the c++0x or from boost.
That would be
boost::function<int(int)>
and then use bind to bind your function to this type.
Have a look here and here
Ok here would be a example. I hope that helps.
int MyFunc1(int i)
{
std::cout << "MyFunc1: " << i << std::endl;
return i;
}
int MyFunc2(int i)
{
std::cout << "MyFunc2: " << i << std::endl;
return i;
}
int main(int /*argc*/, char** /*argv*/)
{
typedef boost::function<int(int)> Function_t;
Function_t myFunc1 = boost::bind(&MyFunc1, _1);
Function_t myFunc2 = boost::bind(&MyFunc2, _1);
myFunc1(5);
myFunc2(6);
}
You can store a function in a variable in c++ in this way
auto function_name = [&](params){
statements
};
auto add = [&](int a,int b){
return a+b;
};
cout<<add(5,6);
typedef unsigned int (*PGNSI)(unsigned int);
PGNSI variable1 = func_1;
PGNSI variable2 = func_2;
unsigned int (* myFuncPointer)(unsigned int) = &func_1;
However, the syntax for function pointers is awful, so it's common to typedef them:
typedef unsigned int (* myFuncPointerType)(unsigned int);
myFuncPointerType fp = &func_1;
IF you have Boost installed, you can also check out Boost Function.