C ++在非内联函数中使用typedef

时间:2010-05-14 01:05:33

标签: c++ typedef typename

我有一个这样的课程

template< typename T >
class vector {
  public:
    typedef T &       reference;
    typedef T const & const_reference;
    typedef size_t    size_type;

    const_reference at( size_t ) const;
    reference at( size_t );

以后在同一个文件中

template< typename T >
typename vector<T>::const_reference    // Line X
vector<T>::at( size_type i ) const
{
    rangecheck();
    return elems_[ i ];
}


template< typename T >
reference                              // Line Y
vector<T>::at( size_type i )
{
    rangecheck();
    return elems_[ i ];
}

X行编译正常,但Y行无法编译。来自g ++(版本4.4.1)的错误消息是:

foo.h:Y: error: expected initializer before 'vector'

由此我得知,如果我想要非内联函数,那么我必须完全限定typedef名称,如第X行所示。(注意,size_type没有问题。)

然而,至少在我看来,X线看起来很笨拙。

有替代方法吗?

3 个答案:

答案 0 :(得分:4)

是的,在类外成员函数定义中,您必须为嵌套返回类型使用完全限定名称。这个BTW与模板无关。这也是非模板类的方式。

在您的情况下,它是一个模板类,因此,由于您使用限定名称来引用依赖模板类中的嵌套类型,因此必须在其前面添加关键字typename

但是,您只需要限定返回类型。参数类型不需要限定

template< typename T >
typename vector<T>::const_reference
  vector<T>::some_method( const_reference r ) const
{
  // ...
}

您也可以选择为参数类型使用限定名称,但在这种情况下,您必须执行与返回类型相同的操作(出于同样的原因):在{{1}之前添加它关键字

typename

答案 1 :(得分:3)

从Effective C ++项目42:“无论何时在模板中引用嵌套的依赖类型名称,都必须在它前面加上单词typename。” size_t不嵌套在依赖于模板参数的任何内容中。你确实键入了它,但它总是size_t。

这看起来像size_type DID 依赖于模板参数。

#include <cstddef>

template< typename T >
class vector {
  public:
    typedef T &       reference;
    typedef T const & const_reference;

    const_reference at( typename T::size_type ) const;
    reference at( typename T::size_type );
};

template< typename T >
typename vector<T>::const_reference
vector<T>::at( typename T::size_type i ) const
{
    // ...
}

template< typename T >
typename vector<T>::reference
vector<T>::at( typename T::size_type i )
{
    // ...
}

struct Foo
{
    typedef size_t size_type;
};

int main()
{
    vector<Foo> f;
    return 0;
}

size_type是Foo的嵌套类型。

答案 2 :(得分:2)

你是对的;类型需要限定,因为typedef已在类的范围内给出,而不是在全局范围内。我不知道如何在不污染全球范围的情况下美化它,这将是一个坏主意。但是,看起来你的功能很短,所以为什么不简单地将它们内联?这样可以节省很多额外的打字,恕我直言,它更容易阅读。