C++ passing an object to a function, the operator= is not called - visual-c++

So here is the code snippet:
class MyClass { public: MyClass(char chIn) { std::cout <<
"Constructor!" << std::endl; }
MyClass & operator= (char chIn) { std::cout << "Assigment
operator!" << std::endl; } } ;
void Func(MyClass objIn) { return; }
int _tmain(int argc, _TCHAR* argv[]) { Func('T'); system("PAUSE");
return 0; }
In the upper example the constructor of the object is called!!!! Why is this behavior? Shouldn't the assigment operator be called? Because we're assigning a value to the function parameter, aren't we?

operator= invoked for already existent object otherwise constructor(or copy constructor) is used to create needed instance

Related

how to invoke thread without creating static function [duplicate]

I am trying to construct a std::thread with a member function that takes no arguments and returns void. I can't figure out any syntax that works - the compiler complains no matter what. What is the correct way to implement spawn() so that it returns a std::thread that executes test()?
#include <thread>
class blub {
void test() {
}
public:
std::thread spawn() {
return { test };
}
};
#include <thread>
#include <iostream>
class bar {
public:
void foo() {
std::cout << "hello from member function" << std::endl;
}
};
int main()
{
std::thread t(&bar::foo, bar());
t.join();
}
EDIT:
Accounting your edit, you have to do it like this:
std::thread spawn() {
return std::thread(&blub::test, this);
}
UPDATE: I want to explain some more points, some of them have also been discussed in the comments.
The syntax described above is defined in terms of the INVOKE definition (§20.8.2.1):
Define INVOKE (f, t1, t2, ..., tN) as follows:
(t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of
type T or a reference to an object of a type derived from T;
((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of the types described in the previous
item;
t1.*f when N == 1 and f is a pointer to member data of a class T and t 1 is an object of type T or a
reference to an object of type T or a reference to an object of a
type derived from T;
(*t1).*f when N == 1 and f is a pointer to member data of a class T and t 1 is not one of the types described in the previous item;
f(t1, t2, ..., tN) in all other cases.
Another general fact which I want to point out is that by default the thread constructor will copy all arguments passed to it. The reason for this is that the arguments may need to outlive the calling thread, copying the arguments guarantees that. Instead, if you want to really pass a reference, you can use a std::reference_wrapper created by std::ref.
std::thread (foo, std::ref(arg1));
By doing this, you are promising that you will take care of guaranteeing that the arguments will still exist when the thread operates on them.
Note that all the things mentioned above can also be applied to std::async and std::bind.
Since you are using C++11, lambda-expression is a nice&clean solution.
class blub {
void test() {}
public:
std::thread spawn() {
return std::thread( [this] { this->test(); } );
}
};
since this-> can be omitted, it could be shorten to:
std::thread( [this] { test(); } )
or just (deprecated)
std::thread( [=] { test(); } )
Here is a complete example
#include <thread>
#include <iostream>
class Wrapper {
public:
void member1() {
std::cout << "i am member1" << std::endl;
}
void member2(const char *arg1, unsigned arg2) {
std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
}
std::thread member1Thread() {
return std::thread([=] { member1(); });
}
std::thread member2Thread(const char *arg1, unsigned arg2) {
return std::thread([=] { member2(arg1, arg2); });
}
};
int main(int argc, char **argv) {
Wrapper *w = new Wrapper();
std::thread tw1 = w->member1Thread();
std::thread tw2 = w->member2Thread("hello", 100);
tw1.join();
tw2.join();
return 0;
}
Compiling with g++ produces the following result
g++ -Wall -std=c++11 hello.cc -o hello -pthread
i am member1
i am member2 and my first arg is (hello) and second arg is (100)
#hop5 and #RnMss suggested to use C++11 lambdas, but if you deal with pointers, you can use them directly:
#include <thread>
#include <iostream>
class CFoo {
public:
int m_i = 0;
void bar() {
++m_i;
}
};
int main() {
CFoo foo;
std::thread t1(&CFoo::bar, &foo);
t1.join();
std::thread t2(&CFoo::bar, &foo);
t2.join();
std::cout << foo.m_i << std::endl;
return 0;
}
outputs
2
Rewritten sample from this answer would be then:
#include <thread>
#include <iostream>
class Wrapper {
public:
void member1() {
std::cout << "i am member1" << std::endl;
}
void member2(const char *arg1, unsigned arg2) {
std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
}
std::thread member1Thread() {
return std::thread(&Wrapper::member1, this);
}
std::thread member2Thread(const char *arg1, unsigned arg2) {
return std::thread(&Wrapper::member2, this, arg1, arg2);
}
};
int main() {
Wrapper *w = new Wrapper();
std::thread tw1 = w->member1Thread();
tw1.join();
std::thread tw2 = w->member2Thread("hello", 100);
tw2.join();
return 0;
}
Some users have already given their answer and explained it very well.
I would like to add few more things related to thread.
How to work with functor and thread.
Please refer to below example.
The thread will make its own copy of the object while passing the object.
#include<thread>
#include<Windows.h>
#include<iostream>
using namespace std;
class CB
{
public:
CB()
{
cout << "this=" << this << endl;
}
void operator()();
};
void CB::operator()()
{
cout << "this=" << this << endl;
for (int i = 0; i < 5; i++)
{
cout << "CB()=" << i << endl;
Sleep(1000);
}
}
void main()
{
CB obj; // please note the address of obj.
thread t(obj); // here obj will be passed by value
//i.e. thread will make it own local copy of it.
// we can confirm it by matching the address of
//object printed in the constructor
// and address of the obj printed in the function
t.join();
}
Another way of achieving the same thing is like:
void main()
{
thread t((CB()));
t.join();
}
But if you want to pass the object by reference then use the below syntax:
void main()
{
CB obj;
//thread t(obj);
thread t(std::ref(obj));
t.join();
}

ability to run a packaged task with std::bind function parameters in a seperate thread via template function

The question i have is the line where i indicate ERROR below gives error as std::thread constructor works out the function to be invoked and requires
the parameter as needed by the function signature.
Is there any way to solve this ? if i attempt to decode the function name and argument list from packaged_task then i cant use the get_future function over packaged task and need to add my own promise/future code to handle this.
#include<iostream>
#include<string>
#include<thread>
#include<future>
#include<functional>
using namespace std;
int sampleAddFunction(const int& a, const int& b)
{
int sum = a + b;
cout << "sum = " << sum << endl;
return(sum);
}
template<typename T> T asyncExecutor(std::packaged_task<T(T, T)>&& package)
{
std::future<T> result = package.get_future();
std::thread task_td(std::move(package)); // ERROR here as the std::thread identifies the function name from package and requires the params to be passed. How to handle this ?
task_td.join();
return(result.get());
}
int main(int argc, char* argv[])
{
// Executing via directly calling through main.
int testResult1 = sampleAddFunction(100, 200);
cout << "testResult1 = " << testResult1 << endl;
// Attempt to create a std::packaged_task and then run it in another thread.
std::packaged_task<int(int,int)> task(std::bind(sampleAddFunction, 10, 20));
std::future<int> result = task.get_future();
std::thread t(std::move(task), 100, 200); // 100 and 200 are dummy parameters.
t.join();
int testResult2=result.get();
cout << "testResult2 = " << testResult2 << endl;
// Attempt to run this in seperate thread and get results.
std::packaged_task<int(int,int)> task2(std::bind(sampleAddFunction, 15, 27));
int testResult3 = asyncExecutor<int>(std::move(task2), 100, 200);
cout << "testResult3 = " << testResult3 << endl;
}
This should work.
#include<iostream>
#include<string>
#include<thread>
#include<future>
#include<functional>
using namespace std;
int sampleAddFunction(int a, int b)
{
int sum = a + b;
cout << "sum = " << sum << endl;
return(sum);
}
template<typename R, typename F, typename... Ts>
R asyncExecutor(F&& package, Ts... args)
{
std::future<R> result = package.get_future();
std::thread task_td(std::move(package), args...);
task_td.join();
return(result.get());
}
int main(int argc, char* argv[])
{
std::packaged_task<int(int,int)> task2(sampleAddFunction);
int testResult3 = asyncExecutor<int>(std::move(task2), 15, 27);
cout << "testResult3 = " << testResult3 << endl;
}
You are constructing a binary packaged_task (std::packaged_task<int(int,int)>) from a nullary function, the result of your bind (std::function<int()>).
You should either not use bind, or have asyncExecutor accept a nullary packaged_task (std::packaged_task<T()>)
int sampleAddFunction(const int& a, const int& b)
{
int sum = a + b;
cout << "sum = " << sum << endl;
return(sum);
}
template<typename T, typename ... ARGS> T asyncExecutor(std::packaged_task<T(ARGS...)>&& package, ARGS ... args)
{
std::future<T> result = package.get_future();
std::thread task_td(std::move(package), args...);
task_td.join();
return(result.get());
}
int main(int argc, char* argv[])
{
std::packaged_task<int()> task(std::bind(sampleAddFunction, 10, 20));
int testResult = asyncExecutor(std::move(task));
cout << "testResult = " << testResult << endl;
std::packaged_task<int(int,int)> task2(sampleAddFunction);
int testResult2 = asyncExecutor(std::move(task2), 15, 27);
cout << "testResult2 = " << testResult2 << endl;
}

Copy constructor is being called instead of the move constructor

I'm trying to use the new C++11 move semantics, but the copy constructor gets called every time... Does anyone know what am I doing wrong? I'm using VS2012. Thanks in advance!
MemoryBlock::MemoryBlock(MemoryBlock& other)
: m_capacity(other.m_used), m_used(other.m_used), m_pointer(nullptr) {
std::wcout << L"Copy constructor called" << std::endl;
// ...
}
MemoryBlock& MemoryBlock::operator=(MemoryBlock& other) {
std::wcout << L"Copy assignment called" << std::endl;
if (this != &other) {
// ...
}
return *this;
}
MemoryBlock::MemoryBlock(MemoryBlock&& other)
: m_capacity(other.m_capacity), m_used(other.m_used), m_pointer(other.m_pointer) {
std::wcout << L"Move constructor called" << std::endl;
// ...
}
MemoryBlock& MemoryBlock::operator=(MemoryBlock&& other) {
std::wcout << L"Move assignment called" << std::endl;
if (this != &other) {
// ...
}
return *this;
}
MemoryBlock CreateRequest(const wchar_t *action) {
MemoryBlock request;
// ...
return request;
}
int __cdecl wmain(int argc, wchar_t *argv[]) {
// ...
MemoryBlock request = CreateRequest(argv[1]);
// ...
}

Making changes to future object

I am trying to change the behavior of a future object based on user input.
#include <iostream>
#include <future>
//=======================================================================================!
struct DoWork
{
DoWork(int cycles, int restTime) : _cycles(cycles), _restTime(restTime), _stop(false)
{
}
void operator () ()
{
for(int i = 0 ; i < _cycles; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(_restTime));
if(_stop)break;
doTask();
}
}
void stop()
{
_stop = true;
}
private:
void doTask()
{
std::cout << "doing task!" << std::endl;
}
private:
int _cycles;
int _restTime;
bool _stop;
};
//=======================================================================================!
int main()
{
DoWork doObj(50, 500);
std::future<int> f = std::async(std::launch::async, doObj);
std::cout << "Should I stop work ?" << std::endl;
std::cout << "('1' = Yes, '2' = no, 'any other' = maybe)" << std::endl;
int answer;
std::cin >> answer;
if(answer == 1) doObj.stop();
std::cout << f.get() << std::endl;
return 0;
}
//=======================================================================================!
However this does not stop the execution of the future object. How do I change the behavior of the doObj after I have created the future object?
You have a few problems. First, your function object doesn't actually return int, so std::async will return a std::future<void>. You can fix this either by actually returning int from DoWork::operator(), or by storing the result from async in a std::future<void> and not trying to print it.
Second, std::async copies its arguments if they aren't in reference wrappers, so the doObj on the stack is not going to be the same instance of DoWork that is being used by the asynchronous thread. You can correct this by passing doObj in a reference wrapper a la std::async(std::launch::async, std::ref(doObj)).
Third, both the main thread and the asynchronous thread are simultaneously accessing DoWork::_stop. This is a data race and means the program has undefined behavior. The fix is to protect accesses to _stop with a std::mutex or to make it a std::atomic.
Altogether, program should look like (Live at Coliru):
#include <iostream>
#include <future>
//=======================================================================================!
struct DoWork
{
DoWork(int cycles, int restTime) : _cycles(cycles), _restTime(restTime), _stop(false)
{
}
int operator () ()
{
for(int i = 0 ; i < _cycles; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(_restTime));
if(_stop) return 42;
doTask();
}
return 13;
}
void stop()
{
_stop = true;
}
private:
void doTask()
{
std::cout << "doing task!" << std::endl;
}
private:
int _cycles;
int _restTime;
std::atomic<bool> _stop;
};
//=======================================================================================!
int main()
{
DoWork doObj(50, 500);
std::future<int> f = std::async(std::launch::async, std::ref(doObj));
std::cout << "Should I stop work ?" << std::endl;
std::cout << "('1' = Yes, '2' = no, 'any other' = maybe)" << std::endl;
int answer;
std::cin >> answer;
if(answer == 1) doObj.stop();
std::cout << f.get() << std::endl;
}
//=======================================================================================!

Runnable implementation using packaged_task in c++11

I am trying to create a Runnable interface in c++11 using packaged_task, with child class overriding run() function. I don't know why this code is not compiling. Its giving error related to type argument.
/usr/include/c++/4.8.1/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of()>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
Below is my code snippet. Could someone plz give me some information on this error and whether implementing Runnable this way is a right way to proceed ?
class Runnable {
public:
explicit Runnable() {
task_ = std::packaged_task<int()>(&Runnable::run);
result_ = task_.get_future();
std::cout << "starting task" << std::endl;
}
virtual int run() = 0;
int getResult() {
task_();
return result_.get();
}
virtual ~Runnable() {
std::cout << "~Runnable()" << std::endl;
}
private:
std::future<int> result_;
std::packaged_task<int()> task_;
};
class foo : public Runnable {
int fib(int n) {
if (n < 3) return 1;
else return fib(n-1) + fib(n-2);
}
public:
explicit foo(int n) : n_(n) {}
int run() {
cout << "in foo run() " << endl;
int res = fib(n_);
cout << "done foo run(), res = " << res << endl;
return res;
}
~foo() {}
private:
int n_;
};
int main(int argc, char*argv[]) {
stringstream oss;
oss << argv[1];
int n;
oss >> n;
shared_ptr<foo> obj(new foo(n));
obj->run();
cout << "done main" << endl;
return 0;
}

Resources