C++ Threads and Member Function Overloading With Multiple Arguments - c++

(Note that the following is an just example based on real code)
Foo.hpp:
#include <thread.h>
#include <iostream>
#include <string>
class Foo
{
private:
std::thread t;
std::string s;
int x;
int y;
public:
Foo();
Foo(std::string s, int x, int y);
void init();
void init(std::string s, int x, int y);
};
Foo.cpp:
#include "Foo.cpp"
Foo::Foo()
{
this->thread = std::thread(static_cast<void (Foo::*)()>(&Foo::init), this);
}
Foo::Foo(std::string s, int x, int y)
{
this->thread = std::thread(static_cast<void (Foo::*)()>(&Foo::init), this, s, x, y);
}
// Foo::init() and Foo::init(std::string s, int x, int y) definitions
This causes g++ to output quite a lot of errors, the most notable of which is likely
no match for call to '(std::_Bind<std::_Mem_fn<void (Foo::*, std::basic_string<char>, int, int)>) ()' (*upCall)();
^
So what am I doing wrong here?

Related

make prototype of overloading function c++

I want to make a overloading function with a prototype in C++.
#include <iostream>
using namespace std;
int rectangle(int p, int l);
int main() {
cout << rectangle(3);
return 0;
}
int rectangle(int p) {
return p*p;
}
int rectangle(int p, int l) {
return p*l;
}
I got error at
int rectangle(int p, int l);
is that possible make prototype with a overloading function? if possible how to do it
You've to declare the function before you use/call it. You did declare the 2 argument version of rectangle function but you seem to forget to declare the 1 argument taking version.
As shown below if you add the declaration for the 1 argument version then your program works(compiles).
#include <iostream>
using namespace std;
//declare the function before main
int rectangle(int p, int l);
int rectangle(int p);//ADDED THIS DECLARATION
int main() {
cout << rectangle(3);
return 0;
}
//define the functions after main
int rectangle(int p) {
return p*p;
}
int rectangle(int p, int l) {
return p*l;
}
The output of the program can be seen here.
Alternative solution:
If you don't want to declare each function separately then you should just define them before main instead of declaring them as shown below.
#include <iostream>
using namespace std;
//define the functions before main. This way there is no need to write a separate function declaration because all definition are declarations
int rectangle(int p) {
return p*p;
}
int rectangle(int p, int l) {
return p*l;
}
int main() {
cout << rectangle(3);
return 0;
}

Using a member function pointer within a class with global typedef

I get a compiler error at the line func = &Fred::fa; saying:
[Error] '((Fred*)this)->Fred::func' cannot be used as a member pointer
since it is of type 'fptr {aka double (*)(int, int)}. However, I know that if I define the typedef as a class inside the class
typedef double (Fred::*fptr)(int x, int y);
then it will not error it. But I want to be sure that the typedef is defined outside the class.
What am I doing wrong?
#include <iostream>
typedef double (*fptr)(int x, int y);
class Fred
{
private:
//typedef double (Fred::*fptr)(int x, int y);
fptr func;
public:
Fred()
{
func = &Fred::fa;
}
void run()
{
int foo = 10, bar = 20;
std::cout << (this->*func)(foo,bar) << '\n';
}
double fa(int x, int y)
{
return (double)(x + y);
}
};
int main ()
{
Fred f;
f.run();
return 0;
}
A function and a method are different. You cannot stuff a pointer to the method in a pointer to a function. So
typedef double (*fptr)(int x, int y);
must be
typedef double (Fred::*fptr)(int x, int y);
or you must use a wrapper that hides the differences such as std::function.
What's missing in
#include <iostream>
typedef double (Fred::*fptr)(int x, int y); // Fred unknown.
class Fred
{
...
}
is a forward declaration for Fred. You can't use Fred is the compiler doesn't know Fred exists.
Solution: Forward declare Fred.
#include <iostream>
class Fred;
typedef double (Fred::*fptr)(int x, int y); // Fred known enough to get pointers
class Fred
{
...
}
But what you really want is std::function.

C++ Linking Issue

Let's say I have a shared library called libfoo.so that also depends on another shared library called libbar.so. In libfoo.so, the only capability it provides is a class that stores two integers and can return the value of those two integers added together.
libfoo.so:
// Foo.hpp
class Foo
{
int x, y;
public:
Foo(int x, int y);
int add() const;
};
Now, in libbar.so, there are two classes: a Bar1 class that simply stores a string and a Bar2 class that stores an integer that is calculated by creating a Foo object and using the add() function to generate a new integer.
// Bar1.hpp
class Bar1
{
std::string str;
public:
Bar1(const std::string& str);
const std::string& getString() const;
};
// Bar2.hpp
#include "foo.hpp"
class Bar2
{
int z;
public:
Bar2(int x, int y);
int getInt() const;
};
Now, I want to write a program that uses Bar1. I do not care about Bar2. My very simple program looks like this:
// Test.cpp
#include <iostream>
#include "Bar1.hpp"
using namespace std;
int main()
{
Bar1 bar1("Hello");
cout << bar1.getString() << endl;
}
I compile this program like so:
g++ -c test.cpp -o test.o
g++ -o test test.o -lbar
The error that is generated is:
undefined reference to 'Foo::Foo(int, int)'
undefined reference to 'Foo::add() const'
This can be fixed by specifying '-lfoo' to the linker. However, I am now linking in a library that my binary will never use.
Is there a way to clean this up where the compiler understands that my binary does not care about resolving these symbols since I never use Bar2 anywhere in my program?
EDIT:
Adding the implementations of the classes. I didn't think that it mattered. Here they are:
// Foo.cpp
#include "Foo.hpp"
Foo::Foo(int new_x, int new_y)
{
x = new_x;
y = new_y;
}
int Foo::add() const
{
return x + y;
}
And here is Bar1.cpp:
// Bar1.cpp
#include "Bar1.hpp"
Bar1::Bar1(const std::string& the_str)
{
str = the_str;
}
const std::string& Bar1::getString() const
{
return str;
}
And here is Bar2.cpp:
// Bar2.cpp
#include "Bar2.hpp"
Bar2::Bar2(int x, int y)
{
Foo foo(x, y);
z = foo.add();
}
int Bar2::getInt() const
{
return z;
}
Note that it should be obvious that I am writing these classes like this purely for experimentation purposes. I am playing around with the linker and how a developer would link to libraries and use them.
where is foo.cpp and bar.cpp? you didn't implement classes foo and bar:
// foo.cpp
#include "Foo.hpp"
Foo::Foo(int X, int Y) : x(X), y(Y){}
int Foo::add()const{return x + y;}
// Bar1.cpp
#include "bar1.hpp"
Bar1::Bar1(const std::string& STR) : str(STR){}
const std::string& Bar1::getString() const{return str;}
// Bar2.cpp
#include "foo.hpp"
Bar2::Bar2(int X, int Y) : x(X), y(Y) {z = x + y;}
int Bar2::getInt() const{ return z;}

Linking error: undefined reference within the same class

I am getting the following error with g++ 4.9:
basis.cpp:16: undefined reference to `Basis::foo(int, int)'
This is the header file:
#ifndef BASIS_H
#define BASIS_H
#include "common.h"
#include <math.h>
#include "xdouble.h"
using namespace std;
class Basis {
private:
int rank;
int dim;
public:
Basis(); //Empty constructor
Basis(int r, int d); //Default constructor
void foo(int a, int b);
void bar(int a, int b);
};
#endif
The basis.cpp file is the following:
#include "basis.h"
Basis::Basis()
{
rank = 0;
dim = 0;
}
Basis::Basis(int r, int d) // Default constructor
{
rank = r;
dim = d;
}
void Basis::bar(int a, int b)
{
void foo(int a, int b);
}
void Basis::foo(int a, int b)
{
}
Even though I'm including the basis.h file I get the undefined reference error and I can't understand why this is happening. What am I doing wrong?
Thanks
It looks like a copy and paste error. Try this:
void Basis::bar(int a, int b)
{
foo(a, b);
}
You made a mistake because you copied and pasted the definition of the function foo in the place where you wanted to call this function.

Error: "undefined reference to 'function'" in C++

I got an error while compiling C++:
/tmp/ccqs6UN2.o: In function main': PowerModulus.cpp:(.text+0x194): undefined reference to takeModulusLOOP(int, int, int)' collect2: ld returned 1 exit status
The source code:
#include "PowerModulus.h"
#include <iostream>
int modint(int x, int moduint);
int takeModulusLOOP(int x, int n, int moduint);
int main() {
std::cout << takeModulusLOOP(5348, 700, 335);
}
int PowerModulus::takeModulusLOOP(int x, int n, int moduint) {
int total = modint(x, moduint);
n--;
while (--n) {
total = modint(total * x, moduint);
}
return total;
}
int PowerModulus::modint(int x, int moduint) {
while (x < 0) // Deal with negative
x += moduint;
return x % moduint; // Comes out positive now -> %
}
PowerModulus::PowerModulus() {
// TODO Auto-generated constructor stub
}
PowerModulus::~PowerModulus() {
// TODO Auto-generated destructor stub
}
Header file:
#ifndef POWERMODULUS_H_
#define POWERMODULUS_H_
int modint(int x, int moduint);
int takeModulusLOOP(int x, int n, int moduint);
class PowerModulus {
public:
int takeModulusLOOP(int x, int n, int moduint);
int modint(int x, int moduint);
PowerModulus();
virtual ~PowerModulus();
};
#endif /* POWERMODULUS_H_ */
Where is the error?
You have declared a global takeModulusLOOP function, then call it in main, without ever defining it. This is a different function than PowerModulus::takeModulusLOOP.
// main.cpp
#include "PowerModulus.h"
#include <iostream>
int main(){
std::cout << PowerModulus::takeModulusLOOP(5348,700,335) << '\n';
return 0;
}
Changed to a namespace instead of a class, and separated into header and implementation (instead of grouping in main.cpp):
// PowerModulus.cpp
#include "PowerModulus.h"
namespace PowerModulus {
int takeModulusLOOP(int x, int n, int moduint){
int total = modint(x, moduint) ;
n--;
while (--n){
total = modint( total * x, moduint );
}
return total;
}
int modint(int x, int moduint){
while ( x < 0) // deal with negative
x += moduint;
return x % moduint;//comes out positive now -> %
}
}
Header:
// PowerModulus.h
#ifndef POWERMODULUS_H_
#define POWERMODULUS_H_
namespace PowerModulus {
int modint(int x, int moduint);
int takeModulusLOOP(int x, int n, int moduint);
}
#endif
This line:
std::cout << takeModulusLOOP(5348,700,335);
is calling the non-class takeModulusLOOP, which you haven't defined anywhere.
You should either call the class version, by providing an object of the class type and using something like:
PowerModulus p;
std::cout << p.takeModulusLOOP(5348,700,335);
(most likely) or providing a non-class version (least likely).
You could also consider making the function static since it doesn't seem to require an object at all. Then you don't need to instantiate one.
You receive the error, because you do not have such a function.
Actually, you have it in PowerModulus class, so you should call the function from PowerModulus instance.
PowerModulus pM;
pM.takeModulusLoop(5348,700,335);
You do not need to claim the function in the beginning of your .h file or in the beginning of your .cpp file.
If you intended to use the takeModulusLoop function of the PowerModulus class then you need not declare a global function again...
But, if you intended to use a different global function, then you need to define it in its context...