模板类

时间:2018-01-21 12:05:45

标签: c++ templates

通常,在头文件中声明成员函数并使用源文件来实现它。我理解的原因是函数实现只驻留在一个转换单元中,并且只链接到其他单元(没有重复的代码),它还允许分离接口和实现,并且不需要转发声明函数相互依赖。

但是,模板中的成员函数取决于模板参数,如果将实现放在源文件中,则无法知道。但是,仍然可以在类之外定义这样的函数,但它的主要参数不再适用。

那么,哪个更好?

template <class T>
class A
{
    T m()
    {
        return T();
    }
};

template <class T>
class A
{
    T m();
};

template <class T>
T A::m()
{
    return T();
}

这两段代码如果是inline T A::m()则相同,但没有它会有什么区别吗?如果功能是虚拟的怎么办?它只是编码风格的问题,还是有不同的语义?如果函数足够大,它会阻止重复的代码,还是编译器足够智能,如果它不会带来任何好处,不会内联它?

1 个答案:

答案 0 :(得分:3)

  

这两段代码如果是inline T A::m()则相同,但没有它会有什么不同吗?

对于模板,成员函数隐含inline,用于类定义的内部和外部。

  

如果该功能是虚拟的,该怎么办?

没有任何区别。

  

这只是编码风格的问题,还是有不同的语义?

主要是风格。但是,它会影响名称查找的工作方式。所以,如果我们稍微修改类定义

template <class T>
class A
{
    using foo = T;
    foo m();
}; 

我们无法将外部成员定义为

template <class T>
foo A<T>::m()
{
    return T();
}

由于foo的查找在类定义中没有发生,直到资格A<T>::之后。我们需要完全限定foo本身,就像typename A<T>::foo一样。或者也许使用尾随返回类型。

  

如果函数足够大,它是否会阻止重复代码,或者编译器是否足够智能,如果它不会带来任何好处就不能内联它?

这两种风格都不应对其产生负面影响。两者都受到实施质量问题的影响。但是,当然,不同的实现可能具有不同的特性。