在将模板类分为头文件和实现文件时使用类型别名

时间:2018-11-10 14:01:52

标签: c++ templates typedef using

我有一个模板化的类,该类分为一个.hpp文件和一个.ipp,其中有很长的类型。重构时,我想为该类型编写一个类型别名,以便使代码更具可读性。但是无论如何我都无法在.ipp文件中识别类型别名。

这是我要执行的操作的一个简单示例:

container.hpp:

template <class T>
class container {
public:
    using TypeAlias = T;
    container(const TypeAlias& a);
    const TypeAlias& getA() const;
private:
    TypeAlias a;
};

#include "container.ipp"

container.ipp:

template <class T>
container<T>::container(const TypeAlias& a) : a(a)
{

}

template <class T>
const TypeAlias& container<T>::getA() const
{
    return this->a;
}

编译时会发生以下错误:

./container.ipp:8:7: error: unknown type name 'TypeAlias'
const TypeAlias& container<T>::getA() const

很显然,在这种情况下,引入TypeAlias并没有多大意义,但在我的实际程序中,它可能会产生很大的变化。我可以做些什么使TypeAlias在.ipp文件中可用?

1 个答案:

答案 0 :(得分:2)

定义诸如container<T>::getA之类的类成员时,将在类的范围内查找该成员名称(此处为getA)之后的内容,但没有查找。本质上,如果编译器试图按顺序理解事物,那么当声明以const TypeAlias&开头时,它尚不知道应该在container<T>内部查找以找出TypeAlias的含义。

因此,使用常规函数语法,您需要指定TypeAlias是成员类型:

template <class T>
const typename container<T>::TypeAlias& container<T>::getA() const
{
    return this->a;
}

但这是“跟踪返回类型”语法(在C ++ 11及更高版本中有效)的一个优点:只需更改事物的顺序,就可以更简单地在返回类型中使用类的成员:

template <class T>
auto container<T>::getA() const -> const TypeAlias&
{
    return this->a;
}