如何将"using"关键字用于可变参数模板



我有一个variadic模板类,该类可以在构造函数和 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));
}

我如何使用语句声明上述声明,因此它也适用于dummy<f2>

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

如果我正确理解您的问题(?(,您可以将类型特征定义为

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, "!!");
 }

之类的辅助模板
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)...) {};
};

最新更新