3

いくつかのプラットフォームでいくつかの基本的なプリミティブを実装するクロスプラットフォーム ライブラリを作成しています。プリミティブ (つまり、クラス) のすべての実装がすべてのプラットフォームで必要なコア メンバーを提供することを確認するには、次の構成を使用します。

template<typename _Ty> int _MethodVerifyHelper(_Ty);
#define ENSURE_MEMBER_DECL(className, methodName, returnType, ...) typedef char __PROTOTYPE_VERIFIER__[sizeof(_MethodVerifyHelper<returnType (className::*)(__VA_ARGS__)>(&className::methodName))]

次に、次のように書きます。

ENSURE_MEMBER_DECL(Event, TryWait, bool, unsigned);

したがって、Event クラスにbool TryWait(unsigned)メソッドがない場合、ここでコンパイル エラーが発生します。

問題は、コンストラクターへのポインターを宣言するための同様の構文が C++ にあるかどうかです。クラスが指定された引数の型を持つコンストラクターを提供しない場合にコンパイル時エラーを引き起こすステートメントが必要です。

4

2 に答える 2

10

コンストラクターのアドレスを取得する方法はありませんが、特定の引数のセットを使用してオブジェクトを作成できない場合は、コンパイル時エラーが発生する可能性があります。

typedef int dummyToTriggerError[ sizeof( T( arg1, arg2, arg3 ) ) ];

もちろん、本質的な部分はsizeof式です。これには、評価されることはないが、合法でなければならないオブジェクトの構造が含まれています。typedefコードが生成されないように、でラップされています。

于 2012-08-01T10:22:21.373 に答える
3

いいえ、コンストラクターへのポインターを取得することはできません。

特定のコンストラクターが確実に提供されるようにする方法は、非実行コンテキスト内でコンストラクターへの呼び出しをシミュレートすることです (例: sizeof)。

static_assert(sizeof(className(std::declval<arg1_type>(), std::declval<arg2_type>())) > 0, "");
于 2012-08-01T10:21:54.570 に答える