2016-09-28 12 views
3

私はtwo phase name lookupで研究していました。非常に論理的な説明は、の早い段階でエラーをキャッチするC++の哲学であるに従っていることを示すために、one of the main reasoningがそれであることを示しています。テンプレート化されたクラスの不適切な非テンプレート化メソッドのインスタンス化

私の質問は、なぜこの考え方がテンプレート化されていない方法ではないかということです。いつメソッドが呼び出されたかをチェックするのではなく、テンプレート化されたクラスがインスタンス化されたときに、フェーズ2のテンプレート化されていないメソッドをすべてチェックしてみませんか?

例えば:

template <class T> 
struct X { 

    auto foo() // non-templated (important) 
    { 
    T t{}; 
    return t.non_existing(); 
    } 
}; 

int main() 
{ 
    X<int> x; // (1) this compiles OK. 

    // somewhere is a galaxy far far away, 
    // maybe deep inside some unrelated code 
    x.foo(); // (2) the error is here 
} 

あなたはfooがインスタンス化X<int>ため違法であるが、(2)プログラムは、コンパイルし、何の問題もなく動作します書くことがない場合。

fooに電話したかどうかに関係なく、回線(1)にエラーが発生するはずです。

テンプレート化されたクラスを書くときに、テンプレート化されたクラス(1)をインスタンス化するときにエラーが発生する代わりに、問題のあるメソッド(2)を最後に呼び出すまで、

また、X<int>(1)をインスタンス化してもX<int>::foo(2)をコールしないとコードが有効ですか?それとも、 "病気で、診断は必要ない"のようなものですか?後者の場合、これはエラーを早期にキャッチするさらに多くの理由です。

+0

正常性チェック:コード(1)が有効です。理由: '' std :: vector 'のコピーコンストラクタを、コピーできない' T'のために無効化しなければならないと書いたとします。 'push_back(const T&)'などのためのDtto – Angew

+0

@Angew SFINAEでメソッドを無効にすることによって管理されていると想像しました。 – bolov

答えて

6

コードは有効です。

この機能はoperator<またはoperator==という文字列を簡単に記述できるように設計されています。

このオペレータは、盲目的にその要素に<または==を呼び出そうとします。無効な場合は、vector<または==をラップで呼び出すと、コンパイルが失敗します。

しかし、あなたがしなかった場合、vectorは正常に動作します。現代のC++はSFINAE条件付きメソッド技術またはC++ 20を使用して助言する

は、それが有効な操作であればそうvector==<のみを持つことになり、句が必要です。 vectorが設計されたときに成熟したこれらの技術のどれも、そして有効でないところでテンプレートクラスのメソッドを持つ能力は重要な特徴でした。

==が条件付きで存在する無効コードの初期障害の先頭に、==が安全かどうかを検出するコードをラップすることができます。古代の技術ではこのイントロスペクションが許可されていません。私は<が少なくとも1つのケースで安全に呼び出すことができるかどうかを検出するために、標準コンテナテンプレートに特化したカスタム特性を記述しなければなりませんでした。

関連する問題