私が書いているライブラリには、クラスがあります:
template<typename T>
class my_class {};
そして関数:
template<typename T>
void my_function(...) {};
私のコードのユーザーがmy_function<T>
インスタンス化しようとすると、コードのどこかで呼び出されたことを保証したいmy_class<T>
. my_class
つまり、対応するテンプレートをインスタンス化せずにテンプレートをインスタンス化しようとすると、コンパイル エラーを生成したいと考えていますmy_function
。
例:
int main() {
my_func<int>() // cause instantiation of my_func<int>
my_class<int> foo; // okay, because my_func<int> exists
my_class<char> bar; // compile error! my_func<char> does not exist
}
my_class<T>
内部で使用する必要がないmy_func<T>
ので、インスタンス化しても自動的にインスタンス化されないことに注意してくださいmy_func<T>
。
編集[0]:my_func<T>
ユーザーがそれを呼び出して、ライブラリに処理方法を伝える情報を渡す必要があるため、自分自身を呼び出すことはできませんmy_class<T>
。すなわち。a を使用する場合my_class<char>
は、コード内の特定の場所で明示的に指定する必要があります。コンストラクターが呼び出されたmy_class<T>
かどうかをテストmy_func<T>
して、呼び出されていない場合は実行時エラーを生成することもできますが、使用されているかどうかはコンパイル時に認識できるため、コンパイル時にエラーを生成できるようにしたいと考えていますmy_func<T>
。
編集[1]:理想的とは言えない方法の 1 つMY_FUNC
は、そうでなければ不完全なテンプレート クラスのテンプレート特殊化を作成するマクロを作成することです...
template<typename T>
class incomplete;
#define MY_FUNC(T) template<> incomplete<T> { static const bool x = my_func<T>(); };
template<typename T>
class my_class {
template<size_t i>
class empty {};
typedef empty<sizeof(incomplete<T>)> break_everything;
}
現在、ユーザーはmy_class<T>
ifMY_FUNC(T)
がどこかで使用されている場合にのみ使用できます。ただし、マクロを使用せず、ユーザーがMY_FUNC
関数ではなくグローバルスコープで使用することを強制しないソリューションを好みます。
編集[2]:回答ありがとうございます。my_func<T>
ユーザーが間違って呼び出していないことをコンパイル時に保証することは不可能だと認識しています。しかし、そうなる可能性をかなり低くし、早い段階で実行時エラーを発生させることができます。
彼らは、たとえば、と呼ばれる関数を定義することになっていますinitialise_library
。関数は次のようになります。
void initialise_library() {
my_func<int>();
my_func<char>();
etc..
}
my_func
ライブラリの初期化中に、が呼び出されていないことを確認します。次に、 を呼び出しますinitialise_library
。my_funcs
次に、すべてが呼び出されていることを確認します。これだけのことができます。ユーザーが定義initialise_library
していない場合、リンカー エラーが発生します。my_func<T>
プログラムのどこかで使用する aを呼び出していない場合my_class<T>
、(理想的には) コンパイル エラーが発生します。定義initialise_library
してmy_func<T>
どこかで使用したが、間違った場所で使用した場合、プログラムの起動時に実行時エラーが発生します。
my_class<T>
基本的に、私は彼らがコードのどこかに a を追加したり、 を忘れたりするのを止めたいと思ってmy_func<T>()
いinitialise_library
ます。これをランタイム チェックする唯一の方法は、 の構築中ですmy_class<T>
。my_class<T>
彼らが深くてめったに使用されないコードのチャンクでのみ使用する場合、これはこのチェックを行うのに厄介なほど遅い時間になります.