4

サブクラスメソッドが存在する場合、それを呼び出す必要がある init() メソッドを持つテンプレートクラスが 1 つあります。Base クラスのメソッド init() は永久に呼び出します。

template <class T>
class Base
{

   template<typename... Args>
   void init(Args... args);

   T subj;

   explicit Base() { subj = new T(); }
}


template<typename... Args>
Base<T>::init(Args... args)
{
    invoke_if_exists<&T::init,subj>(args); // <-- that moment
}

invoke_if_exists テンプレートを実装する必要があります。アルゴリズムはそのようなコードであるべきです

if ( method_exists(T::init) )
{
     subj->init(Args...);
}   

テンプレートにラップする必要があります

どうもありがとう。

[アップデート]:

少し広く説明してみましょう。

class Foo
{
// ... and there is no init()
};

class Right
{
    void init() { ... }
 /// ...
}


auto a = new Base<Foo>();
auto b = new Base<Right>();

a->init();  // there is no call for Foo::init();
b->init();  // there is correct call for Right::init();

invoke_if_exists<>init() メソッドだけでなく、任意のメソッドを使用したい。

4

1 に答える 1

3

型とデータを受け取り、それらに対して何もしないデータと型のシンク:

struct sink {
  template<typename... Us>
  void operator()(Us&&... us) const {}
};
template<typename... Ts>
struct type_sink:std::true_type {};

template invoke_init_if_exists次に、ターゲットの型Tと一連の引数を取るを作成し、T*->initこれらの引数で呼び出すことができる場合は、そうします。それ以外の場合は、上記のデータ シンクにデータをスローします。

template<typename T,typename ArgTypes,typename=void>
struct invoke_init_if_exists:sink {};
template<typename T,template<typename...>class Pack,typename... Args>
struct invoke_init_if_exists<T,
  Pack<Args...>,
  typename std::enable_if< type_sink<
    decltype( std::declval<T*>()->init( std::declval<Args>()... ) )
  >::value >::type
>
{
  void operator()( T* target, Args&&... args ) const {
    target->init( std::forward<Args>(args)... );
  }
};

init次に、これを使用してメソッドを実装します。

template<typename... Args>
Base<T>::init(Args&&... args)
{
  invoke_init_if_exists<T, type_sink<Args...>>()(&subj, std::forward<Args>(args)...);
}

ここでヘルパー クラスを作成します。これは、への呼び出しが有効かどうかに応じて、sinkまたは何かに転送されます。initinit

method が既にT::initない限り、トークンに有効な名前を付けることができないため、このようなことをしなければならなくなります。そのため、SFINAE コンテキストでルックアップを行うカスタム クラスを作成する必要があり、失敗した場合は何もしないようにフォールバックします。TinitT::init

于 2013-11-13T18:51:31.180 に答える