2017-06-02 70 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)...) {}; 
}; 
相关问题