2017-06-02 9 views
3

私はコンストラクタ内で任意の数の変数を取ることができるバリデーショナルテンプレートクラスを持ち、std::tuple/std::pairなども持っています。バリデーションテンプレートに "using"キーワードを使用する方法

さまざまな戻り値の型を持つ関数にこのラッパーを使用したいと思います。例えば

:私はこのように使用して宣言したいと思います第三のクラスで今

class f1 
{ 
    using output = double; 
    output operator() { do_smth }; 
} 
class f2 
{ 
    using output = std::tuple<double,int>; 
    output operator() { do_smth }; 
} 



template <typename... Types> 
class OutputType 
{ 
    std::tuple<Types...> m_val; 
public: 
    OutputType(std::tuple<Types...>&& val) : m_val(val) {}; 
    OutputType(Types&& ... val) : m_val(std::forward<Types>(Types)...) {}; 
}; 

:それは、正しいことをやって

template <typename F> 
class dummy 
{ 
    using Output = typename OutputType(typename F::Output)); 
} 

がどのようにステートメントを使用して上記を宣言しますdummy<f2>

(すなわちOutputType<double,int>なくOutputType<std::tuple<double,int>>

+0

で次

template <typename F> struct dummy { using output = typename oTypes<typename F::output>::type; }; 

を次のようにdummyを定義しますか?あなたのコードに多くの書式の間違いが含まれています...ここで必要なのはおそらく、 'std :: tuple'の' dummy'を特化することです。 – Holt

+0

タプルをパックに変換し、そのパックを 'OutputType'に送ることができるかもしれません。それがどのように見えるかわからない。タプルをパラメータパックに変換する際には、既にここにはたくさんのものがあります。 – NathanOliver

答えて

4

のようなものにOUTPUTTYPEを変更

template<typename ... Types> 
struct add_tuple { 
    using type = std::tuple<Types...> 
}; 

template<typename ... Types> 
struct add_tuple<std::tuple<Types...>> { 
    using type = std::tuple<Types...> 
}; 

のようなヘルパーテンプレート(?)、あなたを型形質を定義することができます

template <typename ... Types> 
struct oTypes 
{ using type = OutputType<Types...>; }; 

template <typename ... Types> 
struct oTypes<std::tuple<Types...>> 
{ using type = OutputType<Types...>; }; 

、あなたは `f1`のコード少なくとも仕事を提供することができ、完全なコンパイルの例

#include <tuple> 
#include <utility> 

struct f1 
{ 
    using output = double; 

    output operator()() 
    { return 0.0; } 
}; 

struct f2 
{ 
    using output = std::tuple<double,int>; 

    output operator()() 
    { return { 1.0, 2 }; } 
}; 

template <typename ... Types> 
class OutputType 
{ 
    private: 
     std::tuple<Types...> m_val; 

    public: 
     OutputType(std::tuple<Types...>&& val) : m_val(val) 
     { } 

     OutputType(Types&& ... val) : m_val(std::forward<Types>(val)...) 
     { } 
}; 

template <typename ... Types> 
struct oTypes 
{ using type = OutputType<Types...>; }; 

template <typename ... Types> 
struct oTypes<std::tuple<Types...>> 
{ using type = OutputType<Types...>; }; 

template <typename F> 
struct dummy 
{ using output = typename oTypes<typename F::output>::type; }; 

int main() 
{ 
    static_assert(std::is_same<dummy<f1>::output, 
           OutputType<double>>::value, "!"); 
    static_assert(std::is_same<dummy<f2>::output, 
           OutputType<double, int>>::value, "!!"); 
} 
+0

それはまさに私が求めていたものです。それはかなり巧妙な解決策です。私はdecltype()を使うことを考えましたが、それを正しく書く方法は分かりませんでした。 –

+0

@BuckBは答えを受け入れることを検討します... –

0

私が正しくあなたの質問を理解していれば

template <typename... Types> 
class OutputType 
{ 
    typename add_tuple<Types...>::type m_val; 
public: 
    OutputType(typename add_tuple<Types...>::type&& val) : m_val(val) {}; 
    OutputType(Types&& ... val) : m_val(std::forward<Types>(Types)...) {}; 
}; 
関連する問題