我有一个抽象基类,它定义了数据接收器的接口。数据汇的具体实现是通过工厂获得的。为了整理代码,我为工厂方法创建了一个typedef,它从DataSink抽象基类中返回新的DataSink对象。
#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);
如果我然后尝试申报:
boost::function<get_new_data_sink_function_type> getNewDataSinkFunction_;
在某个地方,我得到:
error: field 'getNewDataSinkFunction_' has incomplete type
如果我改为声明:
boost::function<std::auto_ptr<DataSink>(std::string)> getNewDataSinkFunction_;
......一切都很好。
我意识到DataSink是一个不完整的类型,因为它是抽象的,但因为我使用了std :: auto_ptr引用语义,所以应该没问题,对吧?在任何情况下,这都无法解释为什么typedef失败并且typedef定义的剪切和粘贴成功。这是一个带有boost :: function的怪癖吗?
编译器是gcc 4.3.3。任何见解都非常感激。
答案 0 :(得分:3)
get_new_data_sink_function_type
不是函数类型,而是函数指针的类型。 boost::function
需要函数类型(或签名)。
此外,抽象类不必是不完整的类型(并且它不在typedef
的站点上)。警告的“不完整类型”部分可能源于boost::function
可能写成这样的事实:
template<typename Sig>
class function; // Not defined!
template<typename Ret, typename Arg>
class function<Ret(Arg)> {
// ...
};
// Various other specializations
这意味着当使用非函数类型实例化boost::function
时,就像在您的情况下一样,没有特化匹配并且选择了基本模板。由于它没有定义,它是一个不完整的类型。
你可以做的最简单的修复就是让你的typedef
成为一个真正的函数类型,这会使它的名字不再具有误导性:
typedef std::auto_ptr<DataSink> get_new_data_sink_function_type(std::string);
请注意,对此,get_new_data_sink_function_type*
与之前的函数类型指针相同。