I'm doing a wrapper in C ++ for a C library ( libuv , in case there is curiosity).
To keep the code as portable as possible, I am using pointers at the original struct
.
Each type of struct
has its own initialization function; but, in my wrapper , I start from a base class that contains in a union
all possible types of pointers to use.
To initialize those pointers, I have to make a call to a specific C function; for this, my base class is not template , but has a template builder ; the idea is that, from each daughter class, the specific specialization to be used in each case is called.
However, I'm having trouble calling the base-class template-builder:
struct uv_loop_t {
void *data;
};
struct uv_tcp_t {
void *data;
};
void uv_loop_init( uv_loop_t * );
void uv_tcp_init( uv_tcp_t * );
namespace uv {
class uvbase {
protected:
static uv_loop_t *currentLoop;
union {
uv_loop_t *loop;
uv_tcp_t *tcp;
};
template< typename T > uvbase( void * = nullptr );
public:
uvbase( ) = delete;
};
class uvloop: public uvbase {
public:
uvloop( void *d = nullptr ) : uvbase< ::uv_loop_t >( d ) { }
};
}
template< > uv::uvbase::uvbase< uv_loop_t >( void *d ) {
loop = new uv_loop_t;
uv_loop_init( loop );
loop->data = d;
}
template< > uv::uvbase::uvbase< uv_tcp_t >( void *d ) {
tcp = new uv_tcp_t;
uv_tcp_init( tcp );
tcp->data = d;
}
To prove that it is correct, I executed
g ++ -std = c ++ 11 -Wall -Wextra -pedantic -c test.hpp
And I got a pretty sequence of errors:
test.hpp: In constructor 'uv :: uvloop :: uvloop (void *)':
test.hpp: 31: 33: error: 'class uv :: uvbase uv :: uvbase :: uvbase' is not a non-static data member of 'uv :: uvloop'
uvloop (void * d = nullptr): uvbase < :: uv_loop_t > (d) {}
test.hpp: 31: 39: error: expected '(' before '<' token
uvloop (void * d = nullptr): uvbase < :: uv_loop_t > (d) {}
test.hpp: 31: 39: error: use of deleted function 'uv :: uvbase :: uvbase ()'
test.hpp: 26: 3: note: declared here
uvbase () = delete;test.hpp: 31: 39: error: expected '{' before '<' token
uvloop (void * d = nullptr): uvbase < :: uv_loop_t > (d) {}
Next, I changed my class uvloop
to
class uvloop: public uvbase {
public:
uvloop( void *d = nullptr ) : uvbase::uvbase< ::uv_loop_t >( d ) { }
};
in an attempt to indicate explicitly that I want to call a template constructor.
The results did not improve much:
test.hpp: In constructor 'uv :: uvloop :: uvloop (void *)':
test.hpp: 31: 47: error: expected template-name before '<' token
uvloop (void * d = nullptr): uvbase :: uvbase < :: uv_loop_t > (d) {}test.hpp: 31: 47: error: use of deleted function 'uv :: uvbase :: uvbase ()'
test.hpp: 26: 3: note: declared here
uvbase () = delete;test.hpp: 31: 47: error: expected '{' before '<' token
uvloop (void * d = nullptr): uvbase :: uvbase < :: uv_loop_t > (d) {}
- How do I call a specific specialization of the constructor of the base class from the constructor of the daughter class?