2

私はうまくいった次のコードを持っていました:

template<typename T>
class Base {
    virtual void call(T) = 0;
};

class Derived : public Base<int> {
    void call(int);
}

template<typename T>
void registerBase(const Base<T>& ref) {}

このアプローチは、 as が呼び出されたときに as 型を自動検出TできintますregisterBase(Derived())。問題は、次のように切り替えると発生しshared_ptrます。

template<typename T, typename Q>
void registerBase(shared_ptr<Q> ptr) {
    static_assert(is_base_of<Base<T>, Q>::value, "Have to supply a type extending Base<...>");
}

不正な型から保護できますが、型を自動検出できないようですTBase<T>テンプレート推論が機能するように、shared_ptr を自動的にダウンキャストするために使用できるトリックはありますか? または、 typename を見つける別の方法はありTますか?

PS:Q拡張が乗算された場合Base<T>、エラーが発生します (自動推定は失敗するはずです)。

4

1 に答える 1

1

これを行うには、おそらく膨大な数の方法があります。ここに1つあります:

template<class T>
T helper(const Base<T> &); // not defined

template<class Q> 
using base_param = decltype(helper(std::declval<Q>())); 

helper実際のコードでは、detailsおそらく名前空間に入れたいと思うでしょう(そしておそらく名前も変更します)。

Tこれは、返すことができない型 (配列型など)の奇妙なケースがある場合に壊れます。helperの戻り値の型を変更し、それidentity<T>に応じて の定義も変更することで、簡単に修正できbase_paramます。

于 2014-12-03T12:24:02.397 に答える