模板功能中的模板别名

时间:2013-02-01 14:35:28

标签: c++ templates c++11

已编辑:让我们知道我有两个(或更多)模板函数fg,它们使用(有时)类型,具体取决于其模板参数:

template<typename T>
some_ugly_and_large_or_deep_template_struct_1<T>::type 
f(const some_ugly_and_large_or_deep_template_struct_1<T>::type&,
  const some_ugly_and_large_or_deeptemplate_struct_1<T>::type&)
{
   // body, that uses perhaps more times my
   // "some_ugly_and_large_or_deep_template_struct_1<T>"
}

template<typename T>
some_ugly_and_large_or_deep_template_struct_2<T>::type 
g(const some_ugly_and_large_or_deep_template_struct_2<T>::type&,
  const some_ugly_and_large_or_deeptemplate_struct_2<T>::type&)
{
   // body, that uses perhaps more times my
   // "some_ugly_and_large_or_deep_template_struct_2<T>"
}

我如何简化这种“类型”定义?例如,使用任何新的C ++ 11工具?我认为只有类似的事情:

template<typename T,
         typename aux = some_ugly_and_large_or_deep_template_struct_1<T>::type>
aux f(const aux&, const aux&)
{
  // body, that uses perhaps more times my
  // "aux" type
}

template<typename T,
         typename aux = some_ugly_and_large_or_deep_template_struct_2<T>::type>
aux g(const aux&, const aux&)
{
  // body, that uses perhaps more times my
  // "aux" type
}

我用这种方法看到的问题是用户可以提供他自己的aux类型而不是我想要的类型。

4 个答案:

答案 0 :(得分:4)

如果您将其设为可变参数模板,则调用者无法定义以下列出的类型参数:

template<typename T,
         typename..., // firewall, absorbs all supplied arguments
         typename aux = some_ugly_and_large_or_deep_template_struct_1<T>::type>
aux f(const aux&, const aux&)
{
  // body, that uses perhaps more times my
  // "aux" type
}

可选地,为了防止使用太多模板参数意外调用f,可以添加static_assert:

template<typename T,
         typename... F,
         typename aux = some_ugly_and_large_or_deep_template_struct_1<T>::type>
aux f(const aux&, const aux&)
{
  static_assert(sizeof...(F)==0, "Too many template arguments");
  // body, that uses perhaps more times my
  // "aux" type
}

通常情况下,我可以让用户定义类似aux的类型,例如返回类型,这可以为您节省一个演员。

或者您可以将static_assert替换为enable_if

template<typename T,
         typename... F, typename = typename std::enable_if<sizeof...(F)==0>::type,
         typename aux = some_ugly_and_large_or_deep_template_struct<T>::type,>
aux f(const aux&, const aux&)
{
  // body, that uses perhaps more times my                                               
  // "aux" type                                                                          
}

答案 1 :(得分:2)

您可以在函数旁边声明模板别名:

template<typename T> using f_parameter
  = typename some_ugly_and_large_or_deep_template_struct<T>::type;

template<typename T>
f_parameter<T> f(const f_parameter<T>&, const f_parameter<T>&)
{
   f_parameter<T> param;
}

答案 2 :(得分:1)

可能的解决方案是将模板函数转换为template struct operator()。例如:

#include <iostream>
#include <string>

template <typename T>
struct some_ugly_and_large_or_deep_template_struct
{
    typedef T type;
};

template <typename T>
struct f
{
    typedef typename some_ugly_and_large_or_deep_template_struct<T>::type aux;

    aux operator()(const aux& a1, const aux& a2)
    {
        return a1 + a2;
    }
};

int main()
{
    std::cout << f<int>()(4, 4) << "\n";
    std::cout << f<std::string>()("hello ", "world") << "\n";
    return 0;
}

答案 3 :(得分:1)

您可以使用类似

的内容
namespace f_aux {
   template <typename T> using type = 
            typename some_ugly_and_large_or_deep_template_struct<T>::type;
}

template <typename T>
f_aux::type<T> f(const f_aux::type<T>& , const f_aux::type<T>&);

如果f的声明位于合适的命名空间或类中,则可能不需要额外的f_aux命名空间。