如何在类函数的声明和定义中使用基于模板参数的typedef
?
假设我的班级是:
template<class T>
class A
{
typedef T::T1 X;
typedef T::T2 Y;
X& f1(Y& y);
Y& f2(Y& y);
// More declarations
};
所以在定义中,我不能写:
typedef typename T::T1 X;
typedef typename T::T2 Y;
template<class T>
X& A<T>::f1(Y& y) {...}
template<class T>
Y& A<T>::f2(Y& y) {...}
(在我的情况下T
是MaxSimplePathVertex<VertexType<VertexIDType>>
,我还有3个typedef,所以它非常麻烦。
我想我可以将所有typedef 复制到每个函数定义中,但这似乎不是一个优雅的解决方案。
当然,我可以#define X T1
,但通常我会听到人们建议不要使用#define
来处理这类事情。
那么什么是最佳解决方案?
答案 0 :(得分:4)
当您在返回类型中处理模板和成员typedef时,尾随返回类型可以节省开支。你可以简单地说
template<class T>
auto A<T>::f1(Y& y) -> X& {...}
template<class T>
auto A<T>::f2(Y& y) -> X& {...}
在A<T>
模板中查找会员功能名称后面显示的内容,这意味着您不需要将A<T>::
放在他们面前。
答案 1 :(得分:1)
完全拼写出来,因为当返回类型在方法定义之前时,类型在当前命名空间中计算,而不是类方法的命名空间:
template<class T>
class A
{
typedef typename T::T1 X;
typedef typename T::T2 Y;
X& f1(Y& y);
Y& f2(Y& y);
// More declarations
};
template<class T>
typename A<T>::X& A<T>::f1(Y& y) {}
template<class T>
typename A<T>::Y& A<T>::f2(Y& y) {}
struct Foo
{
using T1 = int;
using T2 = double;
};
int main()
{
A<Foo> a;
}
但是当我们使用尾随返回类型时,返回类型将在方法的类的上下文中进行计算,因此它变得更容易:
template<class T>
class A
{
typedef typename T::T1 X;
typedef typename T::T2 Y;
X& f1(Y& y);
Y& f2(Y& y);
// More declarations
};
template<class T>
auto A<T>::f1(Y& y) -> X& // <-- this X is a A<T>::X
{}
template<class T>
auto A<T>::f2(Y& y) -> Y& {}
struct Foo
{
using T1 = int;
using T2 = double;
};
int main()
{
A<Foo> a;
}