代码之家  ›  专栏  ›  技术社区  ›  Arun

C++在非内联函数中使用Type DEFS

  •  3
  • Arun  · 技术社区  · 14 年前

    我有一个这样的班

    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 回复  |  直到 14 年前
        1
  •  4
  •   AnT stands with Russia    14 年前

    是的,在类外成员函数定义中,必须为嵌套的返回类型使用完全限定名。顺便说一句,这与模板无关。非模板类也是如此。

    在您的例子中,它是一个模板类,因此,由于您使用限定名来引用依赖模板类中的嵌套类型,因此必须在它前面加上关键字 typename .

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

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

    您也可以选择对参数类型使用限定名,但在这种情况下,您必须对返回类型执行相同的操作(原因非常相同):用 类别名 关键字

    template< typename T >
    typename vector<T>::const_reference
      vector<T>::some_method( typename vector<T>::const_reference r ) const
    {
      // ...
    }
    
        2
  •  3
  •   Eddy Pronk    14 年前

    从有效的C++项目42:“每当你在模板中引用嵌套的依赖类型名称时,必须立即用单词类型名称来表示它。” 大小不嵌套在依赖于模板参数的任何内容中。你做了typedef,但它的大小总是一样的。

    这就是它的样子,尺寸是什么? 取决于模板参数。

    #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类型。

        3
  •  2
  •   Michael Aaron Safyan    14 年前

    您是正确的;类型需要限定,因为您的typedef是在类的范围内而不是在全局范围内给定的。我不知道如何在不污染全球范围的情况下美化它,这是个坏主意。但是,看起来您的函数很短,所以为什么不直接在内联中定义它们呢?这样可以节省很多额外的打字时间,而且,嗯,它更容易阅读。