1

はここにスコットによっていくつかのC++プログラミング言語語用論からテンプレートコード、ある型引数の型チェックが実行されるのはいつですか?

template<typename T> 
class chooser { 
    public: 
    virtual bool operator()(const T& a, const T& b) = 0; 
}; 

template<typename T, typename C> 
class arbiter { 
    T* best_so_far; 
    C comp; 
public: 
    arbiter() { best_so_far = nullptr; } 
    void consider(T* t) { 
     if (!best_so_far || comp(*t, *best_so_far)) best_so_far = t; 
    } 
    T* best() { 
     return best_so_far; 
    } 
}; 

class case_sensitive : chooser<string> { 
public: 
    bool operator()(const string& a, const string& b) { return a < b; } 
}; 
... 
arbiter<string, case_sensitive> cs_names; // declare new arbiter 
cs_names.consider(new string("Apple")); 
cs_names.consider(new string("aardvark")); 
cout << *cs_names.best() << "\n"; // prints "Apple" 

我々が対象物を(例えば、cs_names)を宣言するたびにarbiter テンプレートの新しいインスタンスを作成しますC++コンパイラ 異なる総称引数セット。 オブジェクトを(例えば、considerを呼び出すことによって)使用しようとするときに限り、 引数がすべての必要な操作をサポートしているかどうかをチェックします。

型チェックを使用の時点まで遅延されているので、chooserクラスについて魔法何も はありません。それを定義するのを怠り、 ヘッダーの外に残した場合は、 のコードはまだコンパイルされて実行されますが、コードはcase_sensitiveです。

は、コンパイル時に以下の二つの時点または実行時にいる:

  • 「使用点」「私たちは、このようなオブジェクトを使用しようとする」時間?

「使用の時点までタイプチェックが遅れる」とは、実行時にタイプチェックが行われることを意味しますか?

ありがとうございました。

答えて

2
  • 時間と
  • 「使用点」「私たちは、このようなオブジェクトを使用しようとしますか」?

いずれも実行時ではなくソースコードを参照します。

この行で:

arbiter<string, case_sensitive> cs_names; 

コンパイラはstd::stringcase_sensitiveを見て、std::stringcase_sensitiveに置き換えCに置き換えTarbiterのバージョンを実装しようとします。

他のタイプの別のarbiterを定義すると、新しいバージョンのarbiterが生成され、コンパイルされます。

0

アランにはその権利があります。

今後の参考として、一般にC++ではコンパイル時にすべてをチェックします。私が知っている唯一の例外は、多態型の動的キャストと、オブジェクトの型を返す関数typeidです。

これらの機能を使用しているのであれば、通常はO-O設計を再考する必要があります。(またはあなたがリファクタリングせずに他の人の壊れたコードを修正しようとしている)。

関連する問題