2016-05-02 9 views
6

私はクラスFilterを持っていますが、これはさまざまな入力にオーバーロードされたprocessメソッドです。すべてのオーバーロードされたメソッドのエイリアス?

template< typename T > 
class Filter 
{ 
public: 
    void process(T arr[], size_t len); 
    T process(T one_value); 
    void process(std::array &arr); 
    void process(std::vector &v); 
    //... many other variants 

    using operator() = process; // How to write proper? 
} 

私はprocessを省略し、ユーザーコードを簡素化したい:filter.process(values)filter(values)なります。私はすべてのバリアントにオーバーロードされたoperator()を書くのは良い考えだとは思わない。より便利なソリューションが存在しなければなりませんか?

答えて

7

あなたは既にミックスにテンプレートを持っているので、どうしてvariadicテンプレートも試してみてください。代わりに、オーバーロードの一部から参照が返された場合(OPには表示されません)。さらに完全性と広いユースケースについて

template <typename... Args> 
decltype(auto) operator()(Args&&... args) 
// caters for reference returns 
{ 
    return process(std::forward<Args>(args)...); 
} 

。必要に応じて、以下はSFINAEに優しい動作を提供し、コンパイラに応じて、短くて簡単なエラーメッセージです。

template <typename... Args> 
auto operator()(Args&&... args) -> decltype(process(std::forward<Args>(args)...)) 
// SFINAE support using a trailing decltype 
{ 
    return process(std::forward<Args>(args)...); 
} 
+0

はちょうどそうのように、代わりにコンストラクタにすべてのそれらのオーバーロードを作ります。 –

+2

タイプチェックをバイパスすることはなく、変換もありません。 'process'は' operator() 'に与えられた引数を受け取ります。 – Niall

+4

@DanKorn私は、現在の標準に準拠したC++コードで 'C++'タグに答えるのはかなり一般的だと思います。つまり、私は 'C++'タグがC++ 03または他の特定の標準を暗示しているとは思わない。 –

8

だけで、operator()をテンプレートユニバーサルリファレンスを使用し、processに引数を完璧フォワード、確かに。適切なヘッダーを追加する必要があります。しかし

template< typename T > 
class Filter 
{ 
public: 
    void process(T arr[], size_t len); 
    T process(T one_value); 
    void process(std::array &arr); 
    void process(std::vector &v); 
    //... many other variants 

    template<typename... Y> 
    auto operator() (Y&&... y) 
     -> decltype(process(std::declval<Y>()...)) 
    { 
     return process(std::forward<Y>(y)...); 
    } 
} 

は、operator()(...)processのすべての過負荷が宣言されなければならないことに注意してください - あなたが質問を編集したおかげTC

+0

私は、ネイルの答えに示されているように、C++ 14の強化された 'auto'リターンタイプの控除のシンプルさを他の人が見ることができるように私の答えを残したいと思います。 – WhiZTiM

+1

@ T.C。私たちは 'declval'を必要としていますか?たぶん 'decltype(プロセス(std :: forward (y)...))'? – Barry

-4

わかりましたので、これはあなたが今求めているものを答え、具体的には、「私がしたいですプロセスを省略したユーザコードを簡素化します:filter.process(値)はフィルタ(値)になります。あなたは、コンパイラによって完全にバイパス型チェックしたいと潜在的に、そして必ず、先に行く微妙なバグの多くを導入した場合

template< typename T > 
class Filter 
{ 
public: 
    void Filter(T arr[], size_t len); 
    T Filter(T one_value); 
    void Filter(std::array &arr); 
    void Filter(std::vector &v); 
    //... many other variants 
}; 
+1

これは、OPがフィルタを呼び出す方法と一致しません。 – NathanOliver

関連する問題