2012-05-15 76 views
1

我最近花了一些時間在我的C++模板中搜索錯字。 g ++沒有抱怨輸入錯誤,所以我想知道是否有一種工具可以在將來檢查這種類型的問題?檢測C++模板問題的工具

這裏是這表明了正確編譯的簡化示例。我會期待一個關於struct dummy的投訴沒有被定義,但是它似乎就像模板化的類goo隱藏了它。

foo.h中:

struct smart { 
    int x, y, z; 
}; 

template<typename T> class goo 
{ 
    void barf(T* ptr){} 
}; 

template<typename T> class foo 
{ 
public: 
    foo(){}; 
private: 
    goo<T> x; 
}; 

class bar: public foo<struct dummy> 
{ 
public: 
    void do_something(struct smart& thing){} 
}; 

Foo.cpp中:如果不使用模板類型參數(這是

#include "foo.h" 

int main() 
{ 
    bar a; 
    struct smart b; 
    a.do_something(b); 
    return b.x+b.y+b.z; 
} 

使用g ++ Foo.cpp中

回答

3

編譯器設置爲最高警告級別,是檢測任何C++問題的最佳工具。

我給你的建議是雙重的:

1)在最高級別設置你的編譯器警告級別。這會吸收許多低級別可能保持沉默的錯誤。

2)使用的編碼風格,是更容易,當你做了錯事產生編譯器錯誤。例如:

class bar: public foo<struct dummy> 
{ 
public: 
    void do_something(struct smart& thing){} 
}; 

老實說我不知道​​這段代碼是否合法。我強烈懷疑不是,但它似乎確實宣佈了一種新型struct dummy。編譯器接受它,所以我不確定它是否合法。

你會一直做這個,而不是服務良好:

class bar: public foo<dummy> 
{ 
public: 
    void do_something(struct smart& thing){} 
}; 

現在,這不能被解析爲一個新的類型聲明,編譯器會拒絕它。這會早早地解決你的問題。

+0

我使用了-Wall,-Wextra和-pedantic,編譯器仍然沒有發現錯誤。有關使用其他/選項[選項](http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html)的任何建議嗎? – Coop

+0

該代碼可能是合法的,如書面。如果是這樣,沒有工具會爲你找到問題,因爲沒有問題 - 這是我的觀點。不要使用'' - 使用''代替。 –

+0

感謝您的澄清和小費。 – Coop

2

編譯成功在你的例子中大小寫)代碼是OK的,即使這個類型不存在,或者你正在調用一個未被調用的成員函數中的類型的函數。這是C++的名稱,如果你不使用它,你不支付它(例如沒有創建新的函數)。

2

這是因爲你用struct dummy編譯器被告知自動生成一個向前聲明結構,如果沒有這樣的結構退出。如果你只使用dummy而不使用struct它不會這樣做,它會抱怨。

0

Attilla已經釘這一點; dummy的定義不需要 ,所以它可以保持不完整的類型。這是C/C++非常有用的功能,因爲它有助於隱藏信息,並且還可以減少編譯時間。

例如:

// Afwd.h 
class A; 
A * getA(); 
void processA(A *); 
void printA (A *); 


// t.cc 
#include "Afwd.h" 
void bar() 
{ 
    A * a = getA(); 
    processA (a); 
    printA (a); 
} 

在這裏,這是不需要的A客戶看到它的實現細節。這也有客戶並不需要包括所需要的的A

定義爲了在原來的例子來產生針對dummy錯誤頭的優勢,定義必須在該轉換單元中使用。

首先,在其中需要一個完整的類型的方式經由解引用使用ptr需要,例如:

template<typename T> class goo 
{ 
public: 
    void barf(T* ptr){ 
     *ptr;   
    } 
}; 

這仍然是不作爲函數barf一個問題不叫,所以是未實例化:

template<typename T> class foo 
{ 
public: 
    foo(){ 
     x.barf (0); 
    }; 
private: 
    goo<T> x; 
}; 

此代碼現在生成一個錯誤。 bar的構造函數實例化並調用foo的定義,該定義實例化並調用barf