の特定のネストされたクラスの非会員の一般的な機能を実装:は、私は以下のクラスを持つクラステンプレート
template<int P>
struct A {
struct B {
auto abs() const { return 1; }
};
};
具体A
はPを法整数の有限体であるはず、とB
が表すクラスですこの有限体からの要素次に、私はabs
関数を使うはずの拡張GCDアルゴリズムの汎用実装を持っています。問題は、拡張型GCDアルゴリズムの実装で、基本型(int、longなど)と同様にA<P>::B
で動作するようにしたいという問題です。だから私はA<P>::B::abs
を呼び出す非会員abs
を実装する必要があります。私は3つのテクニックを試してみましたが、そのうち2つはうまくいかず、もう1つは適切です。
テクニック1(動作しません):引数依存ルックアップ(ADL)を使用します。 A
のボディ内部が、B
の体外以下を定義します。
auto abs(B const &e) { return e.abs(); }
ADLがクラススコープではなく名前空間内のみになりますので、それは動作しません。 UPDATE:abs
がインスタンスメソッドであるため、ADLはここでは機能しません。しかし、T.C.の答えによれば、それを友人の機能にすると正しく動作し、ADLはそれを見つけます!
技術2(動作しない):グローバルまたは名前空間スコープで制約関数テンプレートを使用します。
template<int P>
auto abs(typename A<P>::B const &e) { return e.abs(); }
P
が非推定されるコンテキストにあるので、これはまた、動作しません。
テクニック3(作品が、満足のいくものではない):グローバルまたは名前空間スコープで制約のない関数テンプレートを使用します。
template<typename T>
auto abs(T const &e) { return e.abs(); }
これは動作します。しかし、それは拘束されていない。この関数テンプレートのインスタンス化は、A<P>
(あらかじめわかっているのはP
)と他のクラステンプレート(多項式リングとフィールド拡張用)のみに制限したいと考えています。問題は、P
が推論されていないコンテキストにある場合、SFINAEの使用方法がわかりません。
は、別のソースファイルで、クラスの外に実装し、それが宣言を維持しますが、提供する方法はありますか? –
@ M.Alaggan No.これらは、テンプレート以外の関数のファミリにインスタンス化します。クラステンプレート定義の外にそれを記述する方法はありません。 –