Я должен реализовать связь протокола с портом последовательного порта устройства. Протокол основан на двоичном выражении, где у нас есть заголовок, который содержит вид и длину пакета, необязательный элемент и контрольную сумму.о decltype в C++
Я использую C++ 11 с Visual C++ 2012 с набором инструментов v110_xp.
Моя первая попытка реализовать его, используя следующий класс:
PacketOutA
, PacketOutB
, PacketOutC
являются все классы с общим интерфейсом, у них есть только два метода: begin()
и end()
для доступа к внутренней информации;
У меня есть интерфейс для ответа пакета IPacketIn
, производного класса PacketIn
Орудия общего персонала и дериватов PacketInA
, PacketInB
и так далее.
Класс Communication
используется для отправки и получения данных в порт связи.
Класс ReaderAndValidator
позволяет мне проверить полученный пакет и получить его.
Dispatcher<T>
используется для получения входного пакета corrisponding от requestç
PacketInA doPacketA()
{
PacketA packetA;
Dispatcher<PacketA> disp(communication);
PacketInA result = controller.send(packetA);
return result; // RVO
}
Давайте посмотрим фрагмент кода:
class Communication {
public:
Communication();
template < typename Iterator >
void send(Iterator first, Iterator last) const
{
// send from first to last to
}
template< typename Iterator >
std::vector<char> read(Iterator first, Iterator last) const
{
// read from first to last to
}
private:
// internal stuff
};
class ReaderAndValidator{
public:
ReaderAndValidator(const Communication& comm)
: mComm(comm)
{
}
std::vector<char> read()
{
// read data
return mComm.read(/* params */);
}
private:
const Communication& mComm;
}
template < typename PacketOut >
class Dispatcher{
Dispatcher()
{
static_assert(false, "unable to instantiate Controller");
}
};
template <>
class Dispatcher<PacketOutA> {
public:
Dispatcher(const Communication& comm)
: mComm(comm)
{
}
PacketInA send(const PacketOutA & packet) const
{
mComm.send(std::begin(packet), std::end(packet));
ReaderAndValidator readAndValidate(mComm);
auto body = readAndValidate.read();
// RVO
PacketInA result(std::begin(body), std::end(body));
return result;
}
private:
const Communication& mComm;
};
// same thing for Dispatcher<PacketOutB>, Dispatcher<PacketOutC> and so on
Класс Device
абстрактные операции, что я могу сделать на мой устройство
class Device : private boost::noncopyable {
public:
Device()
{
// init communication
}
void doPacketOutA(int param)
{
PacketOutA packet(param);
recieve(packet);
}
PacketInB doPacketB()
{
PacketOutB packet();
return recieve(packet);
}
private:
template < typename PacketOutKind >
auto recieve(const PacketOutKind& p) -> decltype(Dispatcher<PacketOutKind>::send(p))
{
Dispatcher<PacketOutKind> disp(mCommunication);
return controller.send(p);
}
private:
Communication mCommunication;
};
Но я проблема с полученным методом: как я могу вывести тип возврата в этой ситуации?
Этот дизайн является хорошим выбором? Лучший способ сделать то же самое?
Wow это Ответ на пост, который я когда-либо видел. Теперь он компилирует спасибо. –
Как вы думаете, это плохой дизайн? Или это приемлемо? –
@ elvis.dukaj: Да, я думаю, это приемлемо. Конечно, есть альтернативы, но этот выбор выглядит хорошо для меня. –