C++中typedef和typename关键字的使用

一、在C中使用typedef关键字:是为了给内建类型或用户自定义数据类型定义符号名称,typedef是由编译器执行解释的,比如:

typedef unsigned char Name;
 
typedef struct Books {
    char  title[50];
    char  author[50];
    char  subject[100];
    int   book_id;
} Book;

这样之后标识符Name可以作为类型unsigned char的缩写,Book可以作为结构体struct Books的缩写,可以定义新变量Name c或Book mybook等等。

二、在C++中使用typedef关键字:同样是由编译器执行解释的;并且在class类中使用时具有public和private权限,通过限制该类型别名的作用域来防止冲突;在public作用域下,可以在类外使用该类型别名,但必须使用::作用域符号。在函数内部使用typedef时,这个别名在函数体外是不可使用的。

class demo_a {
public:
	typedef int VALUE;
	VALUE getValue() const;
private:
	VALUE value;
};

demo_a::VALUE demo_a::getValue() const
{
	std::cout << "demo_a::getValue()" << std::endl;
	return value;
}

int main()
{
	demo_a obj_a;
	obj_a.getValue();
	system("pause");
	return 0;
}

三、在C++类模板中使用typedef,编译器要求typedef定义类型转变的时候必须是确定的类型,所以使用时要注意。

template<typename T>
class demo_b {
public:
	typedef T VALUE;
	VALUE getValue() const;
private:
	VALUE value;
};

template<typename T>
demo_b<T>::VALUE demo_b<T>::getValue() const
{
	std::cout << "demo_b::getValue()" << std::endl;
	return value;
}

int main()
{
	demo_b<int> obj_b;
	obj_b.getValue();
	system("pause");
	return 0;
}

这样编译时会报“依赖名称不是类型”的错误,具体如下:

错误原因是:类模板和函数模板只有在实例化时编译器才能知道T的具体类型,在此之前类模板参数T可以是任意一种类型,编译器在遇到<T>和"::"同时出现或者T和"::"同时出现,即类模板和函数模板两种情况时,无法准确识别其后的内容,认为其可能是一个类型或是一个静态成员,一直到实例化这个类模板或函数模板时才能知道,并且默认情况下编译器认为其是静态成员,所以报出“依赖名称不是类型”的错误。

解决办法是:在函数demo_b<T>::VALUE demo_b<T>::getValue() const 前面添加关键字typename加以声明,显式地告诉编译器demo_b<T>::VALUE是一个类型。

template<typename T>
typename demo_b<T>::VALUE demo_b<T>::getValue() const
{
	std::cout << "demo_b::getValue()" << std::endl;
	return value;
}

同样在函数模板中也需要用typename关键字声明类型,具体代码示例如下:

template<typename T>
typename T::size_type getlength(const T&c)
{
	if (c.empty())
		return 0;
	return c.size();
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ ,`typename` 关键字的主要作用是告诉编译器其后面的符号是一个类型名称(type name),而不是一个值(value),以避免编译器的歧义。具体来说,`typename` 关键字可以用于以下两种情况: 1. 在模板使用嵌套类型时,需要使用 `typename` 关键字来告诉编译器其后面的符号是一个类型名称,而不是一个静态成员变量或函数。 例如,假设有以下的模板类: ``` template <typename T> class MyClass { public: typedef T value_type; ... }; ``` 如果在模板类的成员函数使用 `value_type`,需要使用 `typename` 关键字告诉编译器其后面的符号是一个类型名称: ``` template <typename T> void MyClass<T>::foo() { typename MyClass<T>::value_type x; // 使用typename关键字 ... } ``` 2. 在使用模板时,需要使用 `typename` 关键字来告诉编译器其后面的符号是一个类型名称,而不是一个静态成员变量或函数。 例如,假设有以下的模板函数: ``` template <typename T> void foo(typename T::value_type x) { ... } ``` 如果在使用该模板函数时,传递的类型 `T` 有一个名为 `value_type` 的嵌套类型,需要使用 `typename` 关键字告诉编译器其后面的符号是一个类型名称: ``` struct MyStruct { typedef int value_type; }; int main() { MyStruct s; foo<MyStruct>(s); // 使用typename关键字 ... } ``` 总之,`typename` 关键字的作用是告诉编译器其后面的符号是一个类型名称,以避免编译器的歧义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值