`
RednaxelaFX
  • 浏览: 3052934 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

typename关键字的使用

    博客分类:
  • C++
阅读更多
忘了……模板啊忘光了 T T

今天有同学考C++,后来问了我一个问题:要写一个Set类,支持拷贝构造函数、+=、-=、=、<<等运算符的重载。我偷懒用std::list<T>给实现了一个版本,因为那题目貌似原本有要求用链表来实现(但却没说那链表一定要自己实现,OTL),而且直接用STL的set<T>也未免太“没诚意”了,呵呵
但遇到了点小问题:
我想直接把std::list<T>::iterator用作Set<T>的iterator,但是怎么编译都不行,说std::list<T>不是Set<T>的派生类什么的。然后我就严重被郁闷了……

问了axx大才知道原来在std::list<T>::iterator前加上typename关键字就行了。因为std::list<T>在实例化之前,编译器没办法判断iterator到底是成员还是类型,所以会出错。

于是代码就像这样(别笑,大家都是为了偷懒……本来给集合定义一个顺序迭代器也是够怪的,不过不想自己实现内部用的链表啊):
set.h
#ifndef SET_H_INCLUDED
#define SET_H_INCLUDED

#include <list>
#include <iostream>
#include <algorithm>

template<typename T>
class Set {
    std::list<T> m_data;

public:
    typedef typename std::list<T>::iterator iterator;
    typedef typename std::list<T>::const_iterator const_iterator;

    Set( ) { }

    Set( T array[], T count ) {
        for (T i = 0; i < count; ++i) {
            m_data.push_back( array[ i ] );
        }
        m_data.unique( );
    }

    Set( const Set<T>& rhs ) {
        if ( &rhs == this ) return;
        m_data.clear( );
        m_data = rhs.m_data;
    }

    Set<T>& operator =( const Set<T>& rhs ) {
        if ( &rhs == this ) return *this;
        m_data.clear( );
        m_data = rhs.m_data;
        return *this;
    }

    Set<T>& operator +=( const T& value ) {
        if ( std::find( m_data.begin( ), m_data.end( ), value ) == m_data.end( ) ) {
            m_data.push_back( value );
        }
        return *this;
    }

    Set<T>& operator -=( const T& value ) {
        m_data.remove( value );
        return *this;
    }

    iterator begin( ) {
        return m_data.begin( );
    }

    iterator end( ) {
        return m_data.end( );
    }

    const_iterator begin( ) const {
        return ((const std::list<T>&)m_data).begin( );
    }

    const_iterator end( ) const {
        return ((const std::list<T>&)m_data).end( );
    }

    friend std::ostream& operator <<( std::ostream& out, const Set<T>& set ) {
        out << "[";
        typename Set<T>::const_iterator it = set.begin( );
        if ( it != set.end( ) ) {
            out << *it++;
            if ( it != set.end( ) ) {
                for ( ; it != set.end( ); ++it ) {
                    out << ", " << *it;
                }
            }
        }
        out << "]";
        return out;
    }
};

#endif // SET_H_INCLUDED

注意13、14、68行里typename的使用。

main.cpp
#include <iostream>
#include "set.h"

using namespace std;

int main()
{
    int a[] = { 1, 3, 5, 7, 9 };
    int x = 2, y = 3;
    Set<int> s1( a, 5 );
    Set<int> s2;

    s1 += x;
    s2 = s1;
    s2 -= y;

    cout << s1 << endl << s2 << endl;

    return 0;
}


axx大提到还有一个using declaration可以用于从基类把名字引入到派生类的作用域中,嗯这个我也印象模糊了……
C++真是……我还是写得太少了。平时还是应该多写点的
分享到:
评论

相关推荐

    详解C++的模板中typename关键字的用法

    如果一个名称是嵌套在模板类型参数内部的,并且是依赖于模板参数的,那么在引用这个名称时,就需要使用`typename`关键字来明确指出这是一个类型名称。例如: ```cpp template &lt;typename Iterator&gt; struct iterator_...

    阅读材料-C++ 模板中的typename、class关键字.rar_C++ typename_class

    在定义模板时,我们常常会遇到`typename`和`class`这两个关键字,它们在模板声明中扮演着重要的角色。本文将深入探讨这两个关键字的含义和用法。 ### 1. `typename` 关键字 `typename`关键字在模板中用于声明依赖...

    C++的template模板中class与typename关键字的区别分析

    为了告诉编译器`T::const_iterator`是一个类型,我们需要使用`typename`关键字: ```cpp template &lt;typename T&gt; void add(const T& container, T& sum) { typename T::const_iterator iter = container.begin(); ...

    C++关键字typename的深入理解

    本文将深入探讨`typename`的作用、使用场景及其与`class`关键字的区别。 首先,`typename`和`class`在声明模板类型参数时是等价的。如以下模板声明所示: ```cpp template&lt;class T&gt; class Widget; template...

    C++关键字详细使用

    asm auto bad_cast bad_typeid bool break case catch char class const const_cast continue default delete do double dynamic_cast ...typedef typeid typename union unsigned using virtual void volatile while

    编程中国-C++箴言:理解typename的两个含义.txt

    在深入探讨C++中`typename`关键字的双层含义之前,我们先来简要回顾一下C++模板的基础知识。模板是C++的一项强大特性,它允许程序员编写泛型代码,即能够处理不同类型数据的代码。这极大地提高了代码的重用性和灵活...

    c++关键字解释大全

    - **功能**:`case`关键字与`switch`语句结合使用,为不同的值指定不同的执行路径。 - **用法**:每个`case`标签后跟一个具体的值和对应执行的代码块。 #### catch(捕获异常) - **功能**:`catch`用于捕获抛出的...

    C++ 常用关键字

    例如,`template &lt;typename T&gt; class A { ...; };`这里声明了一个名为A的模板。 11. throw:throw是C++中的一种关键字,用于抛出一个异常。例如,`throw std::runtime_error("Error");`这里抛出一个异常。 12. try:...

    c++中typename和class的区别介绍

    // 使用typename关键字 LengthType length = myArr.GetLength(); } ``` 在这里,`typename` 关键字至关重要,因为它指示`T::LengthType`是一个类型,而不是成员变量或成员函数。如果没有`typename`,编译器将无法...

    Why C++ Supports typename and class.txt

    根据标题"Why C++ Supports typename and class"以及描述中提到的“不错的关于C++中typedef和class的使用说明”,我们可以详细分析这两个关键词在C++中的作用和历史背景。 ### `typename`与`class`:模板参数的指示...

    C++关键字大全(67个).txt

    C++关键字大全(67个) asm auto bad_cast bad_typeid bool break case catch char class const const_cast continue default delete do double dynamic_cast else enum except explicit extern false finally float ...

    C++ 类模板和模板类的深入解析

     答:class用于定义类,在模板引入c++后,初定义模板的方法为:template,这里class关键字表明T是一个类型,后来为了避免class在这两个地方的使用可能给人带来混淆,所以引入了typename这个关键字,它的作用同...

    C++关键字-全.docx

    在C++中,关键字具有特殊的含义,它们不能作为标识符(如变量名、函数名)使用。以下是一些C++的关键字及其用途的详细解释: 1. `asm`: 这个关键字在早期的C++中用于嵌入汇编代码,但已被`__asm`替代。然而,现代...

    C语言32以及C++63个关键字及其含义[定义].pdf

    使用class关键字声明一个类。 9. const:常量的,constant所修饰的对象或变量不能被改变,修饰函数时,该函数不能改变在该函数外面声明的变量也不能调用任何非const函数。 10. const_cast:用法:const_cast...

    深入理解c++模板中的class与typename

    正确使用`typename`关键字可以确保代码在不同编译器和标准下都能正常工作。 总结来说,`class`和`typename`在C++模板中并非完全可互换。`class`主要用于声明类,而`typename`则用于指示模板中的从属类型是类型名称...

    c++模板学习记录(自己)

    6. typename关键字 在模板中,`typename`关键字用于告诉编译器某个表达式是一个类型名称,特别是在依赖于模板参数的表达式中。例如,当访问模板参数类的成员时,如果成员是一个类型,我们需要使用`typename`关键字...

    C++关键字及说明解释.pdf

    C++是一种强大的面向对象的编程语言,其语法丰富...这些关键字是C++语言的基础,理解和正确使用它们是编写高效、可靠代码的关键。通过熟练掌握这些关键字,开发者可以充分利用C++提供的强大功能,实现复杂的程序设计。

    C++66个关键字的中文含义

    ### C++66个关键字的中文含义详解 #### asm(汇编) - **用途**:允许在C++程序中嵌入汇编代码。...以上是C++部分关键字的详细解释及使用示例。掌握这些关键字对于理解和编写高效的C++代码至关重要。

Global site tag (gtag.js) - Google Analytics