2016-05-15 13 views
0

場合:エラー私は、次の操作を実行しようとしているブロック

template <class T> 
void foo(T * ptr){ 
    ...a lot of code ... 
    if(std::is_base_of<Bar<T>,T>::value){ 
     Bar<T> & bar = *ptr; 
     ...a lot of code ... 
    } 
    ...a lot of code  
} 

私はバーのサブクラスであると、この関数をコンパイルしていた場合、すべてが正常に動作しますが、私は使用してコンパイルしようとした場合そうではありません。

Bar<T> & bar = *ptr; 

行です。 TBar<T>のサブクラスではないときにこの行が実行されるので、これはどうですか? これが一般的な方法でない場合は、どうすれば正しい方法でこれを達成できますか?

+0

「を実行しない」「コンパイルされていない」と同じではありません。 –

+1

これはテンプレートであり、テンプレートの初期化を停止する条件があっても、コンパイラはそのためのコードを生成する必要があります。 – Rakete1111

+0

ああありがとうございます。私はこれをどのようにして正しい方法で行うことができますか? – Exagon

答えて

1

Bar<T>

Bar<T> & bar = *ptr; 

Tのサブクラスではないので、これはコンパイルエラーになります。これがif()ステートメント内にラップされ、falseと評価され、コードのこのセクションが実行されないという事実は、この事実を変更しません。

正しいアプローチはテンプレートを特化することです。これらの線に沿って

何か:

template <class T, bool is_subclass=std::is_base_of<Bar<T>,T>::value> 
void foo(T * ptr); 

template <class T> 
void foo<T, true>(T * ptr){ 
    ...a lot of code ... 

    Bar<T> & bar = *ptr; 
    ...a lot of code ... 

    ...a lot of code  
} 

template <class T> 
void foo<T, false>(T * ptr){ 
    ...a lot of code ... 

    ...a lot of code  
} 

あなたは今fooテンプレートの2つの異なるバージョン、ないテンプレートパラメータがサブクラスである場合、1のための1つを持っています。

foo()の両方のバージョンで共通コードが大量に発生する可能性があります。共通コードを独自のスタンドアロンのテンプレート関数に分解して、foo()の両方から呼び出すことで、より多くの作業を行う必要があります。

1

これは複数の方法で達成することができるが、一例では、タグディスパッチある:

template <class T> 
void bar(T* ptr, std::true_type) 
{ 
    // ...a lot of code ... 
} 

template <class T> 
void bar(T*, std::false_type) 
{ 
    // do nothing 
} 

template <class T> 
void foo(T * ptr){ 
    //...a lot of code ... 
    bar(ptr, std::is_base_of<Bar<T>,T>{}); 
    //...a lot of code  
} 
関連する問題