2011-01-05 15 views
4

オーバーロードされたtable::scan_index(std::string, ...)メンバー関数を成功させずに呼び出そうとしています。わかりやすくするために、関連していないコードはすべて削除しました。メンバー関数のオーバーロード/テンプレートの特殊化問題

私はtableという名前のクラスを持っています。このクラスは、文字列を特殊なケースとして扱うために、scan_index()というオーバーロードされた/テンプレート化されたメンバ関数を持っています。

class table : boost::noncopyable 
{ 
public: 
    template <typename T> 
    void scan_index(T val, std::function<bool (uint recno, T val)> callback) { 
     // code 
    } 

    void scan_index(std::string val, std::function<bool (uint recno, std::string val)> callback) { 
     // code 
    } 
}; 

その後table::scan_index(T, ...)

class hitlist { 
public: 
    template <typename T> 
    void eq(uint fieldno, T value) { 
     table* index_table = db.get_index_table(fieldno); 
     // code 
     index_table->scan_index<T>(value, [&](uint recno, T n)->bool { 
      // code 
     }); 
    } 
}; 

そして、それをすべてキックオフ最後に、コードを呼び出すテンプレートメンバ関数の数があるhitlistクラスがあります:

hitlist hl; 
// code 
hl.eq<std::string>(*fieldno, p1.to_string()); 

は、問題は、table::scan_index(std::string, ...)を呼び出す代わりに、テンプレート版を呼び出すことです。私は上記のようなオーバーロードと特殊な関数テンプレート(下記)の両方を使用しようとしましたが、何も動作していないようです。このコードを数時間眺めた後、私は何かが分からないように感じます。何か案は?

template <> 
    void scan_index<std::string>(std::string val, std::function<bool (uint recno, std::string val)> callback) { 
     // code 
    } 

更新: 私はscan_index()呼び出しから<T>装飾を落としました。結果は、文字列パラメータで呼び出しがうまくコンパイルということでしたが、(ダブル例えば)他のタイプの呼び出しを、次のエラーが発生しました:

cannot convert parameter 1 from 'double' to 'std::string' 

だから私は、バックテンプレートの特殊化を使用しに行きました。 ( 私は4つのオーバーロード関数をtableクラスからテンプレートscan_index()機能をドロップして簡単に書き込むことによって、この問題を修正:私はVC++ 10.0

ソリューションを使用しています:FYI

error C2784: 'void table::scan_index(T,std::tr1::function<bool(uint,T)>)' : 
    could not deduce template argument for 'std::tr1::function<bool(uint,T)>' 
    from '`anonymous-namespace'::<lambda5>' 

:今、私はこのエラーを取得しますそのうちの3つは署名を除いて同一である)。幸いにも、彼らはすべてかなり短い(10行未満)ので、それほど悪くはありません。

+0

あなたはKoenigの名前検索の問題を強く疑っています。 –

+0

潜在的に関連しています:http://stackoverflow.com/questions/4217733/distance-calculation-error-in-c/4218731#4218731 –

+0

私はここでこれに似た問題がありました:http://stackoverflow.com/questions/3406004テンプレート 'index_table-> scan_index ... – Grammin

答えて

7

あなたはここで明示的にテンプレートメンバーを呼び出す:

index_table->scan_index<T>(value, [&](uint recno, T n)... 

valueは、テンプレートパラメータであるので、あなたがしていることを置き換える問題ないはずです。

index_table->scan_index(value, [&](uint recno, T n)... 
3

あなたが明示的argument-テンプレートを指定しないでくださいそれをテンプレート引数の控除とオーバーロードの解決に任せるべきです。これにより、元のコードで掲示した過負荷を拾い上げて使用することができます。

1

は、この単純化されたテストを(申し訳ありませんが、私はC++ 0xのコンパイラ気圧を持っていない)を調製:

class table 
{ 
public: 
    template <typename T> 
    void scan_index(T val) { 
     std::cout << "template\n"; 
    } 

    template <> 
    void scan_index<int>(int val) { 
     std::cout << "specialization\n"; 
    } 

    void scan_index(int val) { 
     std::cout << "overloaded\n"; 
    } 
}; 

class hitlist { 
public: 
    template <typename T> 
    void eq(T value) { 
     table tbl; 
     tbl.scan_index<T>(value); 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    int i = 0; 
    hitlist hl; 
    hl.eq(i); 
    return 0; 
} 

出力は "専門"(VC9)です。 hitlist :: eqはテンプレートバージョンを明示的に使用するため、テンプレートの特殊化のみが考慮されるからです。あなたがtbl.scan_index<T>(value);tbl.scan_index(value);に変更すると、オーバーロードされたバージョンが呼び出されます。

tbhテンプレートの特殊化がうまくいかない理由がわかりません。おそらくラムダのために、完全ではないC++ 0xサポートですか?どのコンパイラ? C++コンパイラはscan_indexはむしろオーバーロードされたメソッドを探してより専門性を持って認識し、この方法

template <typename T> 
void scan_index(T val, std::function<bool (uint recno, T val)> callback) { 
    // code 
} 
template <> 
void scan_index(std::string val, std::function<bool (uint recno, std::string val)> callback) { 
    // code 
} 

+0

を明示的に呼び出しているので、/ template-function-c-specific-case-for-a-templated-function-c – Puppy

+0

"上記のようなオーバーロードと特殊な関数テンプレート(下記)の両方を使用しようとしました。" なぜlambdaに関連すると思っていたのですか –

+0

これは、クラス内の特殊化を可能にする拡張機能のためVisual C++でのみコンパイルします。他のコンパイラ(GCCなど)では、専門化をクラス外で定義する必要があります。 (http://stackoverflow.com/a/2098016/2319122を参照してください)。 –

0

は、テンプレートの特殊化のようなものではないです。そして、あなたがコード化できるようにしたいと思ったら、特殊なコードをテンプレートの前に置くべきでしょう。

void scan_index(std::string val, std::function<bool (uint recno, std::string val)> callback) { 
     // code 
    } 
template <typename T> 
    void scan_index(T val, std::function<bool (uint recno, T val)> callback) { 
     // code 
    } 
関連する問題