Move konstruktor

0

Cześć ,

Mam problem. Mam taką metodę w klasie

static void metoda( /*...*/ const zmq::message_t &msg )
{
	/*...*/
	else
	{
		std::thread thread( []( const zmq::message_t msg )
		{
			/*...*/
		}, /* ??? */ );

		thread.detach();
	}
}

Jednak nie za bardzo wiem w jaki sposób przekazać msg z parametru metody do wątku. Klasa message_t wygląda tak mniej więcej

class message_t
{
public:

	inline message_t ()
	{
		int rc = zmq_msg_init (&msg);
		if (rc != 0)
			throw error_t ();
	}

	inline explicit message_t (size_t size_)
	{
		int rc = zmq_msg_init_size (&msg, size_);
		if (rc != 0)
			throw error_t ();
	}

	template<typename I> message_t(I first, I last):
		msg()
	{
		typedef typename std::iterator_traits<I>::difference_type size_type;
		typedef typename std::iterator_traits<I>::pointer pointer_t;

		size_type const size_ = std::distance(first, last);
		int const rc = zmq_msg_init_size (&msg, size_);
		if (rc != 0)
			throw error_t ();
		std::copy(first, last, static_cast<pointer_t>(zmq_msg_data (&msg)) );
	}

	inline message_t (void *data_, size_t size_, free_fn *ffn_,
		void *hint_ = NULL)
	{
		int rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_);
		if (rc != 0)
			throw error_t ();
	}

	inline message_t (message_t &&rhs): msg (rhs.msg)
	{
		int rc = zmq_msg_init (&rhs.msg);
		if (rc != 0)
			throw error_t ();
	}

	inline message_t &operator = (message_t &&rhs) ZMQ_NOTHROW
	{
		std::swap (msg, rhs.msg);
		return *this;
	}

	inline ~message_t () ZMQ_NOTHROW
	{
		int rc = zmq_msg_close (&msg);
		ZMQ_ASSERT (rc == 0);
	}
	/*..*/


private:

	//  Disable implicit message copying, so that users won't use shared
	//  messages (less efficient) without being aware of the fact.
	message_t (const message_t&) ZMQ_DELETED_FUNCTION;
	void operator = (const message_t&) ZMQ_DELETED_FUNCTION;
};

Z góry dzięki za pomoce (:

1
#include <iostream>
#include <thread>
#include <functional>
using namespace std;

template<typename T>
struct Message{
    T data;
};

template<typename T>
void printMsg(T msg){
    cout << msg.data;
}

int main(){
    using msg_t = Message<const char *>;
    cout << "Batman! ";
    msg_t msg{"na"};
    thread threads[] = {
        thread(printMsg<msg_t>,              msg),
        thread(printMsg<const msg_t>,        msg),
        thread(printMsg<msg_t &>,        ref(msg)),
        thread(printMsg<const msg_t &>, cref(msg))
    };
    
    for(auto &thread : threads)
        thread.join();
}

http://melpon.org/wandbox/permlink/9oKOHK7KJbbjaoSM

0

Szczerze powiem, że nie ogarniam. W przykładzie użyję std::unique_ptr bo też jest movable non-copyable.

static void metoda( /*...*/ const zmq::message_t &msg )
{
    std::unique_ptr<int> p;
    /*...*/
    else
    {
        std::thread thread( []( std::unique_ptr<int> )
        {
            /*...*/
        }, std::move( p ) );
 
        thread.detach();
    }
}

Tego też nie łyka. Tu http://stackoverflow.com/questions/10001751/stdthread-with-movable-non-copyable-argument miał taki sam problem i niby inny/nowszy kompilator pomógł. Ja mam VS 2013, więc nie wiem czemu nie idzie

1

To po prostu bug w Visual Studio. W VS2015 już to naprawili.

0

Zastanawiam się czy to ze mną jest coś nie tak :/ Jest coś o czym nie wiem? Czy po prostu nie rozumiem przenoszących konstruktorów?

#include <memory>

class A
{
private:
    std::unique_ptr<int> p;

public:
    A()
    {}
    A( const A &&other ) :
        p( std::move( other.p ) )
    {}
};

int main()
{
    A a;

    A b( std::move( a ) );

    return 0;
}
1>------ Build started: Project: ConsoleApplication3, Configuration: Debug Win32 ------
1>  Source.cpp
1>c:\tools\tmp\consoleapplication3\consoleapplication3\source.cpp(13): error C2280: 'std::unique_ptr<int,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function
1>          with
1>          [
1>              _Ty=int
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\memory(1441): note: see declaration of 'std::unique_ptr<int,std::default_delete<_Ty>>::unique_ptr'
1>          with
1>          [
1>              _Ty=int
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Świeżo zainstalowane VS 2015 na fajnym kompie w pracy.

EDIT

w 1441 linijce jest

	unique_ptr(const _Myt&) = delete;

no ale przecież std::move zwraca xvalue

2
A( const A &&other )

Wywal const. Przenoszenie modyfikuje przekazany obiekt.

1 użytkowników online, w tym zalogowanych: 0, gości: 1