2011-06-08 82 views
2

我有一个抽象基类,它定义了数据接口的接口。数据汇的具体实现是通过工厂获取的。为了整理代码,我为factory方法创建了一个typedef,它从DataSink抽象基类中返回新的DataSink对象。使用typedef函数指针的不完整类型

#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

'size_t'参数上的'const'限定符确实不是必需的,删除它们会使代码更好地适合问题(没有水平滚动条)。 – 2011-06-08 05:42:52

+0

你是对的,因为它们是通过价值传递的。我知道'const'的const限定参数已经变成了一个反射......有点过于热情了:) – 2011-06-08 22:41:22

回答

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*是相同的函数指针键入以前的样子。

+0

啊,这是有道理的。我实际上并不知道你可以键入这样的函数签名;我以为你只限于函数指针。我进一步混淆了自己,认为这样可以,因为'boost :: function'对象可以分配给具有兼容签名的常规函数​​指针......为什么我认为这意味着模板参数可以被类似替换,我只能责怪关于暂时的疯狂...... – 2011-06-08 23:13:31

相关问题