描述:
我有一个名为GenericMessage的 C++ 类,它只包含一个 id 和数据作为其成员(参见下面的代码片段 1 - GenericMessage.hxx)。我的意图是序列化这个类的一个实例,并通过实现推送模式的 ZeroMQ 套接字发送它。
序列化和发送任务已在ZMQHandler 类(参见 sendToBE 函数)中实现,该类位于下面代码片段 2所示的头文件名 ZMQHandler.hxx 中。此类由下面第三个代码片段中所示的TestFE.cxx实例化。
GenericMessage 实例的接收和反序列化在TestBE.cxx中实现, 可在下面的第 4 个代码片段中找到。我的意图是通过 ZMQ 套接字(即拉套接字)接收 GenericMessage 实例,对其进行反序列化,然后打印其成员。
问题:
问题是当我编译 TestBE.cxx 时,我遇到了许多涉及模板函数的编译错误。考虑到 TestBE.cxx 中的代码,谁能告诉我在第 4 个代码片段中标有注释的反序列化部分缺少什么?我是一个相对较新的 C++ 程序员,想知道我应该如何解释这些模板函数相关的编译错误,这些错误已列在本文底部(即最后的片段)。第 18 行编译错误的来源在第 4 个代码片段中标记。谢谢。
代码片段 1 (GenericMessage.hxx)
#include <iostream>
#include <string>
#include <sstream>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
template <class T>
class GenericMessage {
public:
GenericMessage():
beId(-1), data(NULL)
{}
GenericMessage(int id, T msg): beId(id), data(msg)
{}
~GenericMessage(){}
T getData()
{
return data;
}
std::string toString()
{
std::ostringstream ss;
ss << getBeId();
std::string ret = ss.str();
return ret;
}
void setBeId(int id)
{
beId = id;
}
int getBeId()
{
return beId;
}
private:
friend class boost::serialization::access;
int beId;
T data;
template <class Archieve>
void serialize(Archieve & ar, const unsigned int version)
{
ar & beId;
ar & data;
}
};
代码片段 2 (ZMQHandler.hxx)
#include "zmq.hpp"
#include "GenericMessage.hxx"
#include <pthread.h>
#include <unistd.h>
#include <cassert>
template <class A>
class ZmqHandler {
public:
ZmqHandler():
mContext(1),
mOutbHandlerSocket(mContext, ZMQ_PUSH)
{
mOutbHandlerSocket.bind ("tcp://*:5555");
}
~ZmqHandler() {}
void sendToBE(GenericMessage<A> &theMsg)
{
std::stringstream ss(std::ios_base::binary| std::ios_base::out| std::ios_base::in);
boost::archive::binary_oarchive oa(ss, boost::archive::no_header);
oa << theMsg;
zmq::message_t msgToSend(sizeof(ss));
memcpy(msgToSend.data(), ss.str().data(), ss.str().length());
if(memcmp(msgToSend.data(), ss.str().data(), ss.str().length()) != 0)
{
printf("memcpy error\n");
}
mOutbHandlerSocket.send(msgToSend);
std::cout << "SENT request: [" << theMsg.toString() << "]" << std::endl;
}
private:
zmq::context_t mContext;
zmq::socket_t mOutbHandlerSocket;
};
代码片段 3 (TestFE.cxx)
#include "ZmqHandler.hxx"
int main ()
{
ZmqHandler<std::string> zmqHandler;
int counter = 1;
while(1)
{
std::string data = "Hello there!\0";
GenericMessage<std::string> msg(counter, data);
zmqHandler.sendToBE(msg);
counter++;
sleep(1);
}
return 0;
}
代码片段 4 (TestBE.cxx)
#include "zmq.hpp"
#include "GenericMessage.hxx"
#include <fstream>
int main ()
{
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_PULL);
std::cout << "Connecting to FE..." << std::endl;
socket.connect ("tcp://localhost:5555");
while(1){
zmq::message_t reply;
socket.recv (&reply);
/* !!!!!!! LINE 18 starts HERE !!!!!!! */
std::stringstream is(reply.data(), std::ios_base::binary| std::ios_base::out| std::ios_base::in);
boost::archive::binary_iarchive ia(is, boost::archive::no_header);
GenericMessage<std::string> msg;
ia >> msg;
std::cout << "RECEIVED: " << msg.toString() << std::endl;
std::cout << "DATA: " << ((std::string)msg.getData()) << std::endl;
}
return 0;
}
TestBE.cxx 的编译输出
g++ -g -c TestBE.cxx GenericMessage.hxx
TestBE.cxx: In function ‘int main()’:
TestBE.cxx:18:104: error: invalid user-defined conversion from ‘void*’ to ‘const __string_type& {aka const std::basic_string<char>&}’ [-fpermissive]
In file included from /usr/include/c++/4.7/string:55:0,
from /usr/include/c++/4.7/bits/locale_classes.h:42,
from /usr/include/c++/4.7/bits/ios_base.h:43,
from /usr/include/c++/4.7/ios:43,
from /usr/include/c++/4.7/ostream:40,
from /usr/include/c++/4.7/iostream:40,
from GenericMessage.hxx:1,
from TestBE.cxx:2:
/usr/include/c++/4.7/bits/basic_string.tcc:214:5: note: candidate is: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>] <near match>
/usr/include/c++/4.7/bits/basic_string.tcc:214:5: note: no known conversion for argument 1 from ‘void*’ to ‘const char*’
TestBE.cxx:18:104: error: invalid conversion from ‘void*’ to ‘const char*’ [-fpermissive]
In file included from /usr/include/c++/4.7/string:55:0,
from /usr/include/c++/4.7/bits/locale_classes.h:42,
from /usr/include/c++/4.7/bits/ios_base.h:43,
from /usr/include/c++/4.7/ios:43,
from /usr/include/c++/4.7/ostream:40,
from /usr/include/c++/4.7/iostream:40,
from GenericMessage.hxx:1,
from TestBE.cxx:2:
/usr/include/c++/4.7/bits/basic_string.tcc:214:5: error: initializing argument 1 of ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ [-fpermissive]
make: *** [TestBE.o] Error 1