[英]Template alias in template function
编辑:让我们假设我有两个(或多个)模板函数f
和g
,根据模板参数使用(有时)类型:
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
类型,而不是我想要的类型。
如果将其设为可变参数模板,则调用者将无法定义以下所列的类型参数:
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
类型,例如返回类型,可以在其中节省演员阵容。
或者,您可以使用enable_if
替换static_assert
:
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
}
您可以在函数旁边声明一个模板别名:
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;
}
一种可能的解决方案是使用operator()
将模板函数转换为template struct
。 例如:
#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;
}
您可以使用类似
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
名称空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.