I’ve got an abstract base class that defines an interface to data sinks. Concrete implementations of data sinks are acquired via factories. In an effort to tidy up code, I created a typedef for the factory method that returns new DataSink objects from within the DataSink abstract base class.
#include <memory>
#include <string>
class DataSink
{
public:
DataSink() { }
virtual ~DataSink() { }
void Open(const std::string path)
{
InternalOpen(path);
}
bool IsOpen()
{
return InternalIsOpen();
}
void Write(const uint8_t* data, const size_t offset, const size_t size)
{
InternalWrite(data, offset, size);
}
void Close()
{
InternalClose();
}
protected:
virtual void InternalOpen(const std::string path) = 0;
virtual bool InternalIsOpen() = 0;
virtual void InternalWrite(const uint8_t* data, const size_t offset, const size_t size) = 0;
virtual void InternalClose() = 0;
};
typedef std::auto_ptr<DataSink>(*get_new_data_sink_function_type)(std::string);
If I then attempt to declare a:
boost::function<get_new_data_sink_function_type> getNewDataSinkFunction_;
somewhere down the road, I get:
error: field 'getNewDataSinkFunction_' has incomplete type
If I instead declare:
boost::function<std::auto_ptr<DataSink>(std::string)> getNewDataSinkFunction_;
…everything is fine.
I realize DataSink is an incomplete type because it is abstract, but because I’m using reference semantics due to the std::auto_ptr, that should be OK, right? In any case, that doesn’t explain why the typedef fails and the cut&paste of the typedef’s definition succeeds. Is this a quirk with boost::function?
Compiler is gcc 4.3.3. Any insight greatly appreciated.
get_new_data_sink_function_typeis not a function type, but the type of a pointer to a function.boost::functionrequires a function type (or signature).In addition, an abstract class need not be an incomplete type (and it’s not at the site of your
typedef). The ‘incomplete type’ part of the warning likely stems from the fact thatboost::functionis possibly written like this:which means that when
boost::functionis instantiated with a non-function type, as in your case, no specialization matches and the base template is selected. Since it is not defined, it is an incomplete type.The simplest fix you can do is make your
typedefa real function type, which would make its name not misleading anymore:Notice that with this,
get_new_data_sink_function_type*is the same pointer to function type as it was previously.