[解決済み] あるクラスが指定されたシグネチャのメンバ関数を持つかどうかを確認する
質問
あるクラスが与えられたシグネチャの特定のメンバー関数を持っているかどうかを検出するテンプレートのトリックについて質問しています。
この問題は、ここに引用されているものと似ています http://www.gotw.ca/gotw/071.htm Sutterの本の項目で、彼は質問に対して、クラスCは特定のシグネチャを持つメンバー関数を提供しなければならない、さもなければプログラムはコンパイルされないと答えています。私の問題では、クラスがその関数を持っている場合に何かをする必要があり、そうでない場合は "他の何かをする必要があります。
同じような問題にboost::serializationが直面しましたが、私は彼らが採用した解決策が好きではありません。特定のシグネチャを持つメンバー関数(彼らの場合は与えられた型の2つのパラメータを受け取る "serialize")を定義しない限り、デフォルトで(あなたが定義しなければならない)自由関数を呼び出すテンプレート関数で、さもなければコンパイルエラーが発生するのです。つまり、侵入的なシリアライズと非侵入的なシリアライズの両方を実装しているのです。
私は2つの理由から、この解決策は好きではありません。
- boost::serialization名前空間にあるグローバルな"serialize"関数をオーバーライドしなければならないので、あなたのクライアントコードの中で名前空間boostと名前空間serializationを開かなければならないのです!押し付けにならないようにするために。
- その解決のためのスタックは は10~12回の関数呼び出しが必要でした。
私はそのメンバー関数を持っていないクラスのためにカスタム動作を定義する必要があり、私の実体は異なるネームスペース内にあります(そして、私は別のものにいる間、あるネームスペースで定義されたグローバル関数をオーバーライドしたくありません)。
このパズルを解くためのヒントを教えてください。
解き方は?
SFINAEを利用することで、コンパイル時に関数の存在を検出することができます。私のコードの例(クラスがメンバ関数 size_t used_memory() const を持つかどうかをテストします)。
template<typename T>
struct HasUsedMemoryMethod
{
template<typename U, size_t (U::*)() const> struct SFINAE {};
template<typename U> static char Test(SFINAE<U, &U::used_memory>*);
template<typename U> static int Test(...);
static const bool Has = sizeof(Test<T>(0)) == sizeof(char);
};
template<typename TMap>
void ReportMemUsage(const TMap& m, std::true_type)
{
// We may call used_memory() on m here.
}
template<typename TMap>
void ReportMemUsage(const TMap&, std::false_type)
{
}
template<typename TMap>
void ReportMemUsage(const TMap& m)
{
ReportMemUsage(m,
std::integral_constant<bool, HasUsedMemoryMethod<TMap>::Has>());
}
関連
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない
-
[解決済み] 関数シグネチャでstd::enable_ifを避けるべき理由
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み】C++コンパイルタイムエラー:数値定数の前に期待される識別子
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較