2015-08-23 96 views
-2

此問題已經有一個答案here除了因爲我讀了上述問題,仍然不知道什麼是錯的事實。編輯:不,它不是這個錯誤的原因是不同的。C++如何從模板類繼承到模板類,具有相同的參數

我試圖做到這一點:

template<typename T> 
class base 
{ 

protected: 

    base() {} 

    virtual ~base() {} 

    virtual void method(void* const voidp) const = 0; 

}; 

template<typename T> 
class child : public base<T> // ERROR: child is not a template type 
{ 

public: 

    child(std::vector<T> arg) 
     : _arg{arg} 
    { 
    } 

    virtual ~child() {} 

    void method(void* const voidp) const 
    { 
     for(template std::vector<T>::const_iterator it = _arg.begin(); it != _arg.end(); ++ it) 
     { 
      method2(voidp, *it); 
     } 
    } 

protected: 

    std::vector<T> _arg; 

}; 

我略有困惑,因爲這似乎是相同的鏈接的例子,除非是我弄錯了?

編輯:這是method2

void method2(void* const voidp, const double& arg) // second argument comes in both double and float formats 
{ 
} 

// so there is also a: void method2(void* const voidp, const float& arg) 
+0

'的std ::矢量 :: iterator'應'類型名稱的std ::矢量 :: const_iterator'和'方法(voidp,*它);'調用內部是錯誤 - 沒有這樣的功能 –

+0

@PiotrSkotnicki對不起,這是一個錯誤,讓我改變這一點。我的最小例子的問題是,我搞砸了,只給了你一半。 – user3728501

+0

類'child'的構造函數有一個sintax錯誤:'_arg {arg}'應該是'_arg(arg)'。 – enzom83

回答

0

不知道爲什麼你會看到

"// ERROR: child is not a template type"

但是你錯過了一個明顯的一點就是它應該是typenamestd::vector<T>::iterator it

而且const_iterator

for(typename std::vector<T>::const_iterator it = _arg.begin(); 
    it != _arg.end(); 
     ++it) 
{ 
    //method(voidp, *it); //<--- Assuming you've this somewhere not shown in current post 
} 
+0

我不認爲這是問題...爲什麼你有迭代器之前的類型名? – user3728501

+0

因爲'std :: vector :: const_iterator'是從屬類型名稱。你也必須提供一個[SSCCE](http://sscce.org/),如果你覺得這不是目前的帖子 – P0W

+0

的問題,我已經做了 – user3728501

-1

除非可能存在預先聲明沒有類模板的類child,否則沒有可能出現該錯誤的原因。

一個原因可能是,你應該使用()而不是{}初始化成員:

child(std::vector<T> arg) 
     : _arg{arg} 
    { 
    } 

應更正爲:

child(std::vector<T> arg) 
     : _arg(arg) 
    { 
    } 

這也是更好地const引用傳遞:

child(const std::vector<T>& arg) 
     : _arg(arg) 
    { 
    } 

但是,也有一些其他的事情,可以提高以輔助程序:


for循環不會編譯:

for(std::vector<T>::iterator it = _arg.begin(); it != _arg.end(); ++ it) 
    { 
     method2(voidp, *it); 
    } 

T是一個從屬名稱,這意味着std::vector<T>::iterator應該更正爲typename std::vector<T>::iterator。你可以閱讀更多關於這here

但是,std::vector<T>::iterator也應該更正爲std::vector<T>::const_iterator。由於函數methodconstconst意味着函數將承諾不修改類的成員的任何任何。但是,vector中的iterator begin()函數不是const限定的,這意味着編譯器不知道是否要修改成員。因此,必須使用過載const_iterator begin() const,以便編譯器明確知道您不會修改任何成員。

另注:

for(const auto& x : _arg) 
{ 
    method2(voidp, x); 
} 

沒有必要在類中聲明public:兩次:如果你正在使用c++11,您可以通過使用範圍,用於循環使迴路短了很多;一旦public已被聲明一次,下面的所有內容都將公開,直到編譯器達到另一個關鍵字protected/private,反之亦然。

請注意,class的默認訪問級別爲private,對於structpublic。因此,你的類可以稍微修改本:

template<typename T> 
class child : public base<T> 
{ 
public: 
    child(const std::vector<T>& arg) 
     : _arg(arg) 
    { 
    } 

    virtual ~child() {} 

    void method(const void* voidp) const 
    { 
     for(typename std::vector<T>::const_iterator it = _arg.begin(); it != _arg.end(); ++ it) 
     { 
      method2(voidp, *it); 
     } 
    } 

protected: 
    std::vector<T> _arg; 
}; 

同樣爲您base類:

template<typename T> 
class base 
{ 
protected: 
    base() {} 
    virtual ~base() {} 
    virtual void method(const void* voidp) const = 0; 
}; 

要與你放置const關鍵字在你的函數聲明是一致的:

您有:void* const voidp然後const double& arg。如圖所示,const關鍵字不一致置於 - 一個後,一個類型之前:

這將是更好採取任一:const void* voidp, const double& argvoid* const voidp, double const& arg一致性。


要完成,我編譯使用MSVC下面的代碼,它工作得很好:

template<typename T> 
    class base 
    { 
    protected: 
     base() {} 
     virtual ~base() {} 
     virtual void method(const void* voidp) const = 0; 
    }; 

template<typename T> 
    class child : public base<T> 
    { 
    public: 
     child(const std::vector<T>& arg) 
      : _arg(arg) 
     { 
     } 

     virtual ~child() {} 

     void method(const void* voidp) const 
     { 
      for(typename std::vector<T>::const_iterator it = _arg.begin(); it != _arg.end(); ++it) 
      { 
       method2(voidp, *it); 
      } 
     } 

    protected: 
     std::vector<T> _arg; 
    }; 

希望這有助於:)

+0

評論您的一些觀點:爲什麼我應該使用()而不是{}進行初始化? – user3728501

+0

更多評論:是的,我複製並粘貼這個很快,所以好吧,它應該是const_iterator,公共/私人標籤相同,並在for循環模板 - 我修改了示例來照顧這一點,這些不是主要問題這裏 – user3728501

+0

最後,我不是一個「自動」的信徒,所以我選擇不使用它......我不喜歡那種馬虎的編程方式...... – user3728501

0

如果你有同樣的問題我,這可能是你在你的代碼的其他地方做了一個friend class定義?在使用不同編譯器和編譯器選項的不同系統上使用我的代碼後,我花費了大量時間進行編譯。我相信這是因爲在某個時候,我從項目的文件中刪除了一行,在檢查此文件時,我認爲它曾經有一個朋友類定義。我認爲這導致編譯器認爲我沒有寫模板類?雖然我不完全相信這是原因。