1

テンプレート関数を含む次のコードがあります。2 番目のパラメーターが列挙型であるこの関数を呼び出すと、テンプレートの特殊化が検出される場合と検出されない場合があります。

両方の場合で列挙型が同じ列挙型であること (たとえば、再定義がないこと) と、他のパラメーターが正しい値であることを確認しました。1 つのコンパイルが -Winline セットで行われることがわかりました (まだ変更しようとはしませんでした)。見る?

class A {
public:
    template <typename T>
    int f(uint32_t id, T const& t, bool cond);

    ...
};

template <typename T>
int A::f(uint32_t id, T const& t, bool cond)
{
   ...
}

template <>
inline int A::f<int>(uint32_t, int const& t, bool cond)
{
   ....
}
4

2 に答える 2

2

初心者の場合、通常、テンプレート関数をオーバーロードする方法としてテンプレートの特殊化を使用することはお勧めできません。テンプレートの特殊化は、関数のオーバーロードとの相互作用が不十分であり、それらがいつ選択されるかを指示するかなり難解なルールがあります。一般に、関数テンプレートを特殊化するよりも、通常の関数のオーバーロードを提供する方がよいと考えられます。

この場合、クラスを次のように変更することをお勧めします。

class A {
public:
    template <typename T>
        int f(uint32_t id, T const& t, bool cond);
    int f(uint32_t id, int t, bool cond);
    ...
};

次に、テンプレートの特殊化をオーバーロードの実装に変更します。C ++関数のオーバーロードが機能する方法により、これにより関数の正しいバージョンがより正確に選択されます。

特定の質問に関しては、コードが常にオーバーロードを呼び出しているとは限らない理由は、C++が列挙型と型を区別するためintです。intsと列挙型の間で変換する方法はありますが、それらは同じものではなく、 intsをキャッチするように設計されたオーバーロードは、列挙型もキャッチすることが保証されていません。列挙されたケースを処理するために、関数を特にオーバーロードする方がおそらく良いでしょう。

于 2011-02-10T03:03:42.033 に答える
0

回答の試みではありませんが、コメントに収まる以上の投稿をしたい...

基本的に、これは GCC 3.4.6 の予想される動作 (列挙型が int 特殊化と一致しない) を示しています。どのコンパイラを使用していますか? エラーを生成する同様の完全なプログラムを実際に提供できますか?

#include <iostream>                                                             

struct A                                                                        
{                                                                               
  public:                                                                       
    template <typename T>                                                       
    void f(const T&) { std::cout << "general\n"; }                              
};                                                                              

template <>                                                                     
void A::f<int>(const int&) { std::cout << "specialised\n"; }                    

enum E1 { Zero, One, Two };                                                     

enum E2 { Max = INT_MAX };                                                      

int main()                                                                      
{                                                                               
    A a;                                                                        
    a.f("abc");                                                                 
    a.f(123);                                                                   
    a.f(Zero);                                                                  
    E1 e = Two;                                                                 
    a.f(e);                                                                     
    a.f(Max);                                                                   
}

出力:

general
specialised
general
general
general
于 2011-02-10T03:55:05.497 に答える