Incomplete type using typedef function pointer
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_type
is not a function type, but the type of a pointer to a function. boost::function
requires 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 that boost::function
is possibly written like this:
template<typename Sig>
class function; // Not defined!
template<typename Ret, typename Arg>
class function<Ret(Arg)> {
// ...
};
// Various other specializations
which means that when boost::function
is 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 typedef
a real function type, which would make its name not misleading anymore:
typedef std::auto_ptr<DataSink> get_new_data_sink_function_type(std::string);
Notice that with this, get_new_data_sink_function_type*
is the same pointer to function type as it was previously.
精彩评论