代码之家  ›  专栏  ›  技术社区  ›  user48956

模棱两可的模板,代码战士

  •  4
  • user48956  · 技术社区  · 15 年前

    下面的代码在VisualC++和GCC中编译,但代码战士失败了

    抱怨的是,对模板的调用是不明确的——不能决定doit(m*)和doit(m const*),即使在每种情况下,参数都是明确的cost或non 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
    
    }
    

    这只是代码勇士编译器的一个错误吗?(或与GCC/Visual C++的错误)。

    1 回复  |  直到 15 年前
        1
  •  5
  •   Faisal Vali    15 年前

    这是代码战士编译器的错误。

    这就是应该发生的事情:

    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
    }
    

    希望有帮助。