c++模板定义和实现分离
2016-07-19 11:45
441 查看
在编写模板的时候,刚开始是将模板定义在头文件,当具体实现是在cpp文件,发现编译没通过.
后发现一篇知乎的提问,好像模板不支持定义和实现分离,应该是需要直接编写在头文件
知乎提问链接:https://www.zhihu.com/question/20630104
template中使用typename
如下:
template<typname T>
void test(T t) {
T::Test test;
test.print();
}
在这个模板函数中,T因为可以传递是任意类型,那么T::Test在实例化的时候,就可能存在Test是T的静态成员变量,或者Test是T中的父类或者其内部定义的一种类型。
那么这就会存在歧义,而用typename T::Test test;声明该模板只能应用于Test为其父类或者其内部定义的一种类型。编译通过。
template中使用typedef typename,
通过上面的也大致可以猜测到其作用,
如
template<typename T>
void test(T t) {
typedef T::Test Test;
Test test;
test.test();
}
这里同样会出现相应的歧义,那么这个Test::Test是什么类型呢,同样是不确定,那么通过typename,来指定这个是一个类类型即可
即typedef typename T::Test Test;
template中使用typedef typename ::template的情况,
有时候我们再查看stl源代码的时候,会发现这种奇特的代码,
如下:
template<typanem T>
class A {
public:
template<typename D>
struct Test {
void test() {}
};
};
template<typename T, typename D>
void test() {
typedef typename A<T>::template Test<D> Test;
Test test;
test.test();
}
上面这段代码中存现typedef typename A<T>::template Test<D> Test;其目的是希望将A中的Test类型,缩写为Test,方便后面直接使用,
但是如果我们直接typedef A<T>::Test<D> Test是不行的
1.第二个<D>会被认为是小于号,不会作为模板语法来解析。(通过A<T>::template Test<D>来解决)
2.正确上面的一样::Test并不能确定Test是哪一种类型。(通过增加typename来解决)
另一个原因是,虽然实际在使用的时候需要在编译器确定具体的类型值,但是在模板定义的时候,各个类型的在这个模板中应该是一个什么类型就应该要被确定了,
而这个确定不是要等待模板特例化的时候在动态根据实际参数做出变化的。
后发现一篇知乎的提问,好像模板不支持定义和实现分离,应该是需要直接编写在头文件
知乎提问链接:https://www.zhihu.com/question/20630104
template中使用typename
如下:
template<typname T>
void test(T t) {
T::Test test;
test.print();
}
在这个模板函数中,T因为可以传递是任意类型,那么T::Test在实例化的时候,就可能存在Test是T的静态成员变量,或者Test是T中的父类或者其内部定义的一种类型。
那么这就会存在歧义,而用typename T::Test test;声明该模板只能应用于Test为其父类或者其内部定义的一种类型。编译通过。
template中使用typedef typename,
通过上面的也大致可以猜测到其作用,
如
template<typename T>
void test(T t) {
typedef T::Test Test;
Test test;
test.test();
}
这里同样会出现相应的歧义,那么这个Test::Test是什么类型呢,同样是不确定,那么通过typename,来指定这个是一个类类型即可
即typedef typename T::Test Test;
template中使用typedef typename ::template的情况,
有时候我们再查看stl源代码的时候,会发现这种奇特的代码,
如下:
template<typanem T>
class A {
public:
template<typename D>
struct Test {
void test() {}
};
};
template<typename T, typename D>
void test() {
typedef typename A<T>::template Test<D> Test;
Test test;
test.test();
}
上面这段代码中存现typedef typename A<T>::template Test<D> Test;其目的是希望将A中的Test类型,缩写为Test,方便后面直接使用,
但是如果我们直接typedef A<T>::Test<D> Test是不行的
1.第二个<D>会被认为是小于号,不会作为模板语法来解析。(通过A<T>::template Test<D>来解决)
2.正确上面的一样::Test并不能确定Test是哪一种类型。(通过增加typename来解决)
另一个原因是,虽然实际在使用的时候需要在编译器确定具体的类型值,但是在模板定义的时候,各个类型的在这个模板中应该是一个什么类型就应该要被确定了,
而这个确定不是要等待模板特例化的时候在动态根据实际参数做出变化的。
相关文章推荐
- 【C++】软件调试工具Dbgview(OutputDebugString())
- NYOJ 疯牛问题(二分搜索+贪心)
- C++多态的实现机制深入理解
- C语言putenv()函数:改变或增加环境变量
- 《C++ 笔记》 Part5 C++ 资源大全中文版
- C++11新特性之新类型与初始化
- C语言getenv()函数:取得环境变量内容
- c++跨平台线程使用实例
- CA证书导入
- C/C++笔记(C语言重要问题,指针与数组篇)
- 看别人的C/C++代码时发现自己所不知道的语法~
- 关于C++中的继承
- C++ unique_ptr
- i2c 与 spi 设备在新版内核中不采用DTS设备树形式 在驱动添加设备信息(board_info)的方法
- [C++]在程序中高效实用STL
- 【链表】C++链表创建、删除、排序,合并
- 除法表达式
- C语言malloc()函数:动态分配内存空间
- C语言运算符优先级列表
- C++中传值、传址与传引用的区别