2012-09-28 108 views
2

可能重複:
Workaround for non-deduced context嵌套模板參數推導

GCC不能推導出參數,這個 '簡單' 的功能。有什麼方法可以幫助編譯器一點點嗎?從GCC 4.7.1

template<int a> struct A 
{ 
    template<int b> struct B 
    { 
    }; 
}; 

template<int a, int b> void test(typename A<a>::template B<b> param) { } 

int main() 
{ 
    A<1>::B<2> b; 

    test<1,2>(b); // works 
    test(b);  // doesn't work 
} 

錯誤消息:

test.cpp: In function 'int main()': 
test.cpp:15:8: error: no matching function for call to 'test(A<1>::B<2>&)' 
test.cpp:15:8: note: candidate is: 
test.cpp:8:29: note: template<int a, int b> void test(typename A<a>::B<b>) 
test.cpp:8:29: note: template argument deduction/substitution failed: 
test.cpp:15:8: note: couldn't deduce template parameter 'a' 
+0

@BoPersson:我同意這是密切相關的,但因爲這個問題涉及到嵌套模板,答案只要不工作。 –

+0

@BoPersson:我的錯。具有該功能是一個朋友模板功能確實有效。在某些情況下,這可能是更好的解決方案。 –

回答

2

雖然這似乎是一個簡單的推論,你想要什麼樣的編譯器做的實際上是相當複雜和緩慢,一般做的,並且它不受C++支持。

解決這個問題的方法之一是創建另一個非嵌套類,它將所有模板參數放在一個地方。然後,您可以讓這個似乎通過從中獲取的是一個嵌套類:

template<int a,int b> struct A_B { 
    /* define your class here */ 
}; 

template<int a> struct A 
{ 
    template<int b> struct B : A_B<a,b> {/*nothing here*/}; 
}; 

template<int a, int b> void test(A_B<a,b> param) { } 

int main() 
{ 
    A<1>::B<2> b; 

    test<1,2>(b); // works 
    test(b);  // works too 
} 

C++ 11還支持模板走樣,這使它成爲一個少許清潔劑,雖然它沒有被廣泛尚不支持:

template<int a> struct A 
{ 
    template<int b> using B = A_B<a,b>; 
}; 

這個問題是密切相關的:

Workaround for non-deduced context

答案只要是有用的您的情況也是如此。如果你可以讓你的函數是朋友,那麼你可以這樣做:

template<int a> struct A 
{ 
    template <int b> 
    struct B 
    { 
    }; 

    template <int b> 
    friend void test(B<b> param) 
    { 
    } 
}; 
+0

一般來說''param'會受到切片或將要求投射(如果通過引用或指針傳遞) – Rost

+0

@Rost:同意它將切片。我添加了一條評論,使其更清晰,派生的嵌套類中不應該有任何內容。我不明白爲什麼一個演員對指針和參考是必要的。 –

+0

在這種情況下,將'B'定義爲'A'沒有多大意義 - 它仍然會在全局範圍內複製,並且不能使用在'A'中定義的任何類型/成員... – Rost