23

最初にコーディングします。

#include <iostream>

using namespace std;

struct A final {};
struct B {};

int main()
{ 
    cout << is_final<A>::value << endl; // Output true
    cout << is_final<B>::value << endl; // Output false

    return 0; 
}

クラスis_finalを実装する方法は?

4

3 に答える 3

30

GCCの__is_final本質的な(PR 51365の)実装者として、ライブラリでは実行できないと確信しています。コンパイラのサポートが必要です。

C ++11のSFINAEforexpression機能を使用すると、非常に巧妙なことができますが、クラスが最終であるかどうかを検出するには、クラスから派生し、派生型をテンプレート引数推論コンテキストでインスタンス化する必要がありますが、クラスは式ではなく宣言で行われます。

また、疑似キーワードが使用されたかどうかだけを知りたいのかfinal、それともプライベートコンストラクターしかないなどの他の理由でクラスを派生できないのかを考える必要があります。

于 2012-12-10T22:23:28.310 に答える
12

型特性は、通常、SFINAE イディオムを使用して実装されます。これは、関数テンプレート宣言内に不適切な形式の可能性のある式を配置します。問題の型名を宣言に代入するとエラーになりますが、エラーはそのコンテキストで抑制されるため、宣言が使用されるかどうかのいずれかになります。ただし、フォールバック オーバーロードは、欠落している可能性のある宣言をバックアップします。別のコードが関数にアクセスして、機密性の高いオーバーロードまたはバックアップのみがインスタンス化されたかどうかを検出します。

finalクラスのテンプレートのインスタンス化中にのみエラーが発生する可能性があるため、これは機能しません。クラスをオーバーロードする方法はありません。また、final から派生した場合に失敗するがコンパイルを停止しないクラスを暫定的に定義する方法もありません。

標準引用、C++11 §14.8.2/8:

関数の型とそのテンプレート パラメーターの型の直接のコンテキストで無効な型と式のみが推定エラーになる可能性があります。[ 注: 置換された型と式の評価は、クラス テンプレートの特殊化および/または関数テンプレートの特殊化のインスタンス化、暗黙的に定義された関数の生成などの副作用をもたらす可能性があります。 context」であり、プログラムの形式が正しくない可能性があります。— エンドノート]

于 2012-12-10T22:32:47.733 に答える
-3

これがあなたが望むものであるかどうかはわかりませんが、あなたはこのようなことをすることができます:

#include <iostream>

struct Foo {};
struct Bar {};

template<typename T>
struct is_final {
    static const bool value = false;
};
template<>
struct is_final<Bar> {
    static const bool value = true;
};


int main(void) {
    std::cout << is_final<Foo>::value << std::endl;
    std::cout << is_final<Bar>::value << std::endl;
}
于 2012-12-10T22:09:00.297 に答える