Re: How to cast from &BYTE to &My_Type ?
Am 20.09.2011 09:17, schrieb int21h:
I have a protocol that describes packages as sets of bytes. Some bytes
have several information included, like struct Format below. I need to
do something like "Named Parameter Idiom". But I don't succeed in
providing an "accessor" that returns something different as &BYTE
(original type). How can I accomplish this (ctor with BYTE param,
operator= didn't work)?
I guess you can simply use a proxy, see below...
typedef unsigned char BYTE;
For the nitpicking record: The code below actually means an octet, not a
byte. A byte is the smallest addressable unit and that can be more or
less than eight bits.
struct Format {
// Does not help: Format(const BYTE&) {}
BYTE layout : 3;
BYTE length : 5;
};
template<int SIZE>
struct Package : public Base<SIZE> {
static const int OFFSET_SOURCE = 1;
static const int OFFSET_TARGET = 2;
static const int OFFSET_FORMAT = 0;
// kind of " Named Parameter Idiom"
BYTE& source() { return data_[OFFSET_SOURCE]; }
BYTE& target() { return data_[OFFSET_TARGET]; }
// Next line won't compile: cannot convert from 'BYTE' to
// 'Format&'
// Don't want to use a reinterpret_cast either.
Format& format() { return data_[OFFSET_FORMAT]; }
};
Just wondering, do you want to provide a single format() method or do
you want layout() and length() methods? In any case, the idea of a proxy
runs along these lines:
struct FormatProxy
{
explicit FormatProxy(BYTE* p):
address(p)
{}
void operator=(Format const& f)
{
// copy 'f' to the address
}
operator Format() const
{
Format res;
// copy 'res' from address
return res;
}
private:
BYTE* address;
};
The basic idea is that you create a type that has overloaded operators
that make it behave similar to a different type. In this case, class
FormatProxy mimicks the behaviour of class Format. If you pass it to a
function expecting a Format, it will invoke the "operator (Format)", if
you assign a Format to it, it will invoke "operator=(Format const&)".
What is still missing is that you hide/disable the compiler-generated
constructor and assignment operators of course, and also a second type
that mimicks the const interface. However, for the const interface you
can straight away return a Format instance.
What it can't do is mimick access to member variables like "layout" and
"length". For those, you would need another pair of proxies nested
inside FormatProxy. Also, you can't pass the proxy to a function taking
a non-const reference to a Format instance.
int main() {
Package<10> package;
package.source() = 0x04; // fine
package.target() = 0x0b; // fine
// Next 2 line(s) won't compile:
package.format().layout = 0x03; // not fine !
package.format().length = 0x1b;
return 0;
}
Of course, the easiest way is to replace things like "x.source() = 10"
with "x.set_source(10)", which would be much less complicated and a bit
less surprising for the reader (at least I don't normally expect an
l-value to be returned from a function). If you want to invest the time
in the readability, you could replace the functions with proxies like
the one sketched above to fix that.
Good luck!
Uli
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]