2009-09-11 45 views
4

下面的代碼編譯在Visual C++和gcc,但未能與代碼戰士曖昧模板,代碼戰士

的抱怨是,在調用模板是模糊的 - doIt方法之間不能決定(M *)和doIt(M const *),即使在每種情況下,參數都是明確的成本或非常量。令人生氣的是,如果我提供第二個模板參數,它決定它不再含糊不清。

template< typename T1, typename T2 > 
T1 const* doIt(T2 const*); 

template< typename T1, typename T2 > 
T1* doIt(T2*); 

class M {}; 
class N : public M {}; 

void f() 
{ 
    M* m1 = NULL; 
    M const* m2 = NULL; 

    doIt<N>(m1); // Fail 
    doIt<N>(m2); // Fail 
    doIt<N,M>(m1); // OK 
    doIt<N,M>(m2); // OK 

} 

這是Code Warrior編譯器的錯誤嗎? (或與gcc/Visual C++錯誤)。

+0

我不知道人們仍然使用良好的「代碼戰士」。他們不是不停止這樣做嗎? – 2009-09-11 23:59:05

回答

5

這是codewarrior編譯器的錯誤。

這是應該發生的事情:

template< typename T1, typename T2 > 
T1 const* doIt(T2 const*); // 1 

template< typename T1, typename T2 > 
T1* doIt(T2*); // 2 

class M {}; 
class N : public M {}; 

void f() 
{ 
    M* m1 = 0; 
    M const* m2 = 0; 

    doIt<N>(m1);  
    // In the above call - the compiler does the following (post argument deduction) 
    // 1) create a viable set of functions { N* doIt1<N,M>(const M*) , N* doIt2<N, M>(M*) } 
    // 2) check the conversion sequences - M* -> M* is better than M* -> const M* 
    // Since doIt2 has a "better" conversion sequence (hard to beat identity) it wins - no ambiguity 


    doIt<N>(m2);  
    // 1) Viable functions: { doIt1<N,M>(const M*), doIt2<N,const M>(const M*) } 
    // 2) Conversion Sequence Ranking: both do identity - so both are good 
    // 3) Check to see if the "mother" template of either candidate is more specialized 
    //  - Since doIt1 theoretically matches fewer types than doIt2, it is unambiguously more specialized (the standard specifies an algorithm to check this) 
    //  - so doIt1 wins 
} 

希望有所幫助。

+1

+1,儘管對於戰士來說,C++ 03中的算法實際上並不能排序(嘗試comeau 8/4/03,它不能排序),但它無法在兩個方向上推導出「T1」。在http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#214修訂的算法可以通過忽略「T1」來完成。我懷疑這就是更新的編譯器所使用的,因爲無論如何它都是直觀的東西。但是當然,對於拒絕第一個電話的勇士來說,這是可恥的。 – 2009-09-12 01:28:40

+0

@litb - 良好的評論,當部分排列這些特定的調用時,它會引起人們注意返回類型的無關性 – 2009-09-12 04:18:24