Hi, I've got a problem with using a template together with a struct
declared inside a function body, see example below. When I compile "g++
-D TEST1 test.cpp" or "g++ -D TEST2 test.cpp" the compiler answers with
"error: no matching function for call to 'Buffer:read()'". "g++ -D TEST3
test.cpp" compiles and runs as expected but is using a globally defined
struct.
Can someone tell me if this compiler error is a bug in the compiler or
something not covered by the C++ standard? Is there any other workaround
besides making the struct global?
Some background: the intention of the buffer class is to hold data
received over network in a binary protocol. There are a lot of different
calling functions which all define their own structs to parse the
protocol. Defining the structs inside the function body right where they
are used makes the source much more readable.
Thanks for any advice,
Tobias Käs
> g++ --version
g++ (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
------------------------------ test.cpp ------------------------------
#include <stdio.h>
#include <assert.h>
class Buffer
{
private:
const char *data_;
size_t size_;
public:
Buffer(const char *data, size_t size):
data_(data), size_(size) { }
template <class T>
inline const T* read()
{
assert(sizeof(T) <= size_);
const T *ptr = reinterpret_cast<const T*>(data_);
data_ += sizeof(T);
size_ -= sizeof(T);
return ptr;
}
};
#ifdef TEST3
struct PkInit3 { unsigned int version; };
#endif
int main(int argc, char* argv[])
{
const char data[] = "\x12\x34\x56\x78";
#ifdef TEST1
Buffer buffer1(data, sizeof(data) - 1);
const struct PkInit1 { unsigned int version; } *pk1;
assert(pk1 = buffer1.read<PkInit1>());
printf("pk1->version=0x%x\n", pk1->version);
#endif
#ifdef TEST2
Buffer buffer2(data, sizeof(data) - 1);
struct PkInit2 { unsigned int version; };
const PkInit2 *pk2;
assert(pk2 = buffer2.read<PkInit2>());
printf("pk2->version=0x%x\n", pk2->version);
#endif
#ifdef TEST3
Buffer buffer3(data, sizeof(data) - 1);
const PkInit3 *pk3;
assert(pk3 = buffer3.read<PkInit3>());
printf("pk3->version=0x%x\n", pk3->version);
#endif
return 0;
}