2017-06-02 75 views
3

我有一個可變參數模板類,可以在構造函數中的任何數量的變量,也是一個std::tuple/std::pair等等。如何使用「使用」關鍵字的可變參數模板

我想用這種包裝的功能具有不同的返回類型。

例如:

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)); 
} 

如何申報上述所以它的正確的事情也using語句爲dummy<f2>

(即OutputType<double,int>,而不是OutputType<std::tuple<double,int>>

+0

你可以提供一個代碼,至少工作'f1'?你的代碼包含大量的印刷錯誤...你需要的可能是爲'std :: tuple'專門設計'dummy'。 – Holt

+0

您可能可以將元組轉換爲包並將該包發送到'OutputType'。不知道如何看起來。儘管將元組轉換爲參數包,但這裏已經有很多東西了。 – NathanOliver

回答

4

(?),你可以定義類型性狀

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

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

,然後定義dummy如下

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

下面是一個完整的編譯例子

#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> 
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> 
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)...) {}; 
}; 
相關問題