2011-04-26 70 views
5

當試着編譯這個(CRTP樣)代碼GCC 4.6.0:沒有在模板類名爲X類模板

template<template<class> class T> struct A; 

template<class T> 
struct B: A<B<T>::template X> { 
    template <class U> struct X { U mem; }; 
}; 

B<int> a;

我得到的errormessage的「TEST.CPP:3:26:錯誤: 'struct B <int>''中沒有名爲'X'的類模板。爲什麼X似乎在類定義之外是不可見的?

+0

我的編譯器有一個問題,這樣的: :A < B ::模板X> X是未聲明的標識符。我坦率地被你的語法弄糊塗了,什麼是B :: template應該是?除此之外,我從未見過:模板 T類。如果有的話,我想我會從你身上學到一些東西;你能解釋一下語法的重要性嗎?這些是什麼? – leetNightshade 2011-04-26 18:01:39

+0

我不確定,但也許約翰尼斯從這個主題的答案可能在這裏幫助:http://stackoverflow.com/questions/4420828/another-bug-in-g-clang-c-templates-are-fun – Nawaz 2011-04-26 18:04:05

+0

@leetNightshade :我不確定,但我認爲你的錯誤信息實際上和我說的是一樣的東西:X在B以外是不可見的(反正我也是這麼理解的)。關於你的第二個問題:「模板 T類」意味着T本身是模板化的。就像那樣,你可以在A的類定義裏面使用類似T 的東西。 – 2011-04-26 18:07:56

回答

4

由於埃米爾·科米爾正確地指出here的問題是,在A實例化的地方,B仍然是一個不完整的類型,而不能使用內模板。

解決方案是將模板X移動到模板B的外部。如果它是獨立的模板B的具體實例T,只需將它移動到命名空間層次,如果是依賴於實例,你可以使用類型性狀:

template <typename T> 
struct inner_template 
{ 
    template <typename U> class tmpl { U mem; }; // can specialize for particular T's 
}; 
template <typename T> 
struct B : A< inner_template<T>::template tmpl > 
{ 
}; 
2

struct B在您指定A<B<T>::template X>作爲基類時仍被視爲不完整類型。

1

您正在嘗試使用B的成員作爲B的父項,從而創建遞歸式的情況。例如,這不會編譯之一:

template<template<class> class T> struct A {}; 

struct B : public A<B::nested> 
{ 
     struct nested {}; 
}; 
+1

這不是真的:我將B作爲模板參數傳遞,我不從它繼承。 – 2011-04-26 18:13:02

+0

@Tom DeCaluwé我改變了我的答案,表明即使作爲模板參數,它仍然被視爲不能用作模板參數的不完整類型。 – 2011-04-26 18:18:59