2011-06-08 80 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

相關問題