2015-12-15 85 views

回答

4

如果某些模板實例導致需要完成類型的代碼生成,則模板參數必須是完整類型,例如,任何需要模板大小的構造參數,成員訪問的使用等。

在你的情況下,根本不使用模板參數。沒有實例化將要求類型完整。我們可以很容易導致錯誤:

struct x; 

template<typename T> void func() 
{ T a; } //requires complete type 

int main() { 
    func<x>(); 
} 

GCC說:

error: 'x a' has incomplete type

如果我們用一個指針或引用,一個完整的類型就沒有必要:

template<typename T> void func() 
{ T* a; } //does not need complete type 

請注意,該類型需要在實例化時間處完成。這意味着只要您在模板中的使用和該模板的實例化之間定義結構,您就可以。這完全編譯:

struct x; 

template<typename T> void func() 
{ T a; } //requires complete type 

struct x{}; //we now define x 

int main() { 
    func<x>(); //instantiation 
} 

注意,在使用時模板類的成員函數只實例化。因此,只要不使用這些成員函數,就可以使用具有成員函數的模板類,該模板類需要具有不完整模板參數的完整類型。

例如,對於這樣的代碼:

struct x; 

template <typename T> 
struct Foo { 
    void bar() { 
    } 

    void baz() { 
     T a; 
    } 
}; 

這是有效的:

Foo<x> a; 
a.bar(); 

但這不是:

Foo<x> a; 
a.baz(); //requires complete type 
3

要求完成x是您需要知道如何在內存中佈置x的任何情況。例如:

struct x; 
template<typename> void func() { 
    // Compiler error: what is x::foo ??? 
    std::cout << x.foo() << std::endl; 
} 
int main() { 
    func<x>(); 
    return 0; 
} 
+1

爲了清楚:如果'結構x'被定義在'func()'定義和'main()'函數之間,這是有效的。 – YSC

3

這是同其他地方一樣:你可以用一個不完整的類型,如果

  • 您只能使用指針類型
  • 或引用
  • 或使用它作爲一個聲明中的參數

不使用訪問成員的指針/引用。

相關問題