2017-08-12 10 views
3

を失敗すると、一部のクラスがextentionクラスを形成継承しています。事はextentionクラスは、それが拡張され、クラス知っている必要があります。はstdを使用:: static_assertでis_base_ofは不完全型に私がやろうとしています何

template<typename Self> 
class Extention 
{ 
    public: 
     void check() const 
     { 
      std::cout << "Extention is valid: " 
         << std::boolalpha 
         << std::is_base_of<Extention, Self>::value 
        << std::endl; 
     } 
}; 
class Foo : public Extention<Foo> {}; 
class Bar : public Extention<void> {}; 

FooBarクラス良いショー、および拡張子の悪い使い方:

これは、単純に次のように達成することができます。

Foo().check(); → Extention is valid: true 
Bar().check(); → Extention is valid: false 

私は、しかし

template<typename Self> 
class Extention 
{ 
    static_assert(std::is_base_of<Extention, Self>::value); 
}; 

を書くために私をもたらしている、コンパイル時にテンプレートの有効性を確認したいとclass Fooが不完全型を持つように、このstatic_assertが間違っている私のgccの遺丘群です。

私は間違っていますか?

編集:私は-std=c++17を使用しています、エラーは私が間違って何をやっているstatic_assert

+1

メンバ関数に 'static_assert'を入れることはできますが、それを機能させるには関数を(おそらくそれを呼び出して)インスタンス化する必要があります。 – HolyBlackCat

+0

@HolyBlackCatをコンストラクタに置くとうまくいくでしょう。あなたが複数のコンストラクタを持っていれば、それは痛いかもしれませんし、エラーが発生しやすくなります。 – Amxx

+0

静的なアサートを持つすべてのコンストラクタにヒットするのではなく、保護された 'Requiredived'から' Extention'テンプレートを派生していますそうすれば、静的なアサートをハングするためのルート保護されたデフォルトのコンストラクタ、 'RequiredBase()'が得られます。または、私はここであなたの目標を誤解したかもしれません。 – WhozCraig

答えて

2

にエラーメッセージがないことではないでしょうか?そのため[meta.rel]

std::is_base_of派生型が完全な型であることが必要です。

BaseDerivedが非組合クラス型であり、おそらく同じタイプのCV-認定バージョンでない場合は、 Derivedは完全なタイプでなければならない。他方の側で

[class.mem/6]状態すなわち:

クラスは、クラス指定の閉鎖}で完全に定義されたオブジェクトのタイプ(または完全なタイプ)であると考えられます。 [...]あなたのケースではありません

。あなたがExtension<Foo>をインスタンス化すると、Foo自体はこれまで完全に定義されているからです。他の点では

、あなたはクラスのスコープでそのstatic_assertを使用することはできません。あなたが望むなら、デストラクタのボディ(私の好みの解決策には、実際には、いくつかの欠点があるにしても)または他の(特別な)メンバメソッドのボディに入れてください。

関連する問題