| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4089 人关注过本帖, 1 人收藏
标题:模板函数/模板类实例化问题
只看楼主 加入收藏
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9032
专家分:54061
注 册:2011-1-18
收藏
得分:0 
我不知道你口中的“实例化”是什么意思
我只说C++标准中的instantiation概念:
假如只有代码
template<typename T> void foo( T t )
{
}
template<> void foo<int>( int t )
{
}
的话,编译此代码,在obj文件中是找不到foo的任何实例的,即存在“生成 void foo<double>(double)、void foo<char*>(char*)、void foo<int>(int)……的规则”,但并不存在“void foo<double>(double)、void foo<char*>(char*)、void foo<int>(int)”

如果源代码写上
template void foo<double>(double)
template void foo<int>(int)
那么编译此代码后,在obj文件中就有了 template void foo<double>(double) 和 template void foo<int>(int)。
这就是所谓的 模板实例化。
传统的方法还有
int main( void )
{
    void foo<double>(double);
    foo( 1.2 ); // 这触发生成 void foo<double>(double)
    foo( 1 ); // 这触发生成 void foo<int>(int)
}
2017-06-16 16:00
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 10楼 韩海0312
我的模板instantiation, 就是指什么时候通过“规则”实例化出对应的类或者函数,

但是我不懂的是如
(a) void f1(Stack<char>); //这里为什么没有实例化出类Stack<char>
(b) Stack<double> &rsd;   //如果实例化模板,b和d 为什么不需要实例化出模板
(d) Stack<char> *sc;
在我觉得,模板是实例化一种类型或者函数的规则,
例如定义一种类型, 如(a) 这时候为什么不需要类型的(Stack<char>)完整定义,
在比如为什么(b) 和(d) 不要实例化出对应的类型,
我看到的一个解释是这样的:
notice the pointer/reference stuff: they don't require instantiation since no data is actually allocated(a pointer
is just a few bytes to contain the address, has no need to have all the data stored.. take a look at the pimpl idiom ).
Only when stuff is allocated then the template has to be completely resolved (and that happens at compile-time, that's why they usually need both declaration and definition.. there's no linking phase yet)
这种解释其实在说,例如指针32位机中都是4字节,不需要了解类型到底是真么样子的,只有在实例化类对象的时候踩需要实例化模板类,
这怎么又把类对象和模板类的实例化搞在一起,很是费解

抛开显示话声明和定义不讲,模板只有在使用时才实例化,这个“使用该怎么解释”?
2017-06-16 16:44
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 11楼 rjsp
是不是我说道哪里不对啊
2017-06-19 10:26
韩海0312
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2012-8-11
收藏
得分:0 
回复 11楼 rjsp
我好像理解了这个问题,不知道我感觉是对的,你可你帮我分析一下我的理解么

我的理解是这样的:
1.其实模板的实例化是个编译链接问题
假如不考虑模板,我们写几个.cpp (a.cpp, b.cpp)文件,假如a.cpp 文件中使用了b.cpp文件里的类型
使用的时候不需要考虑是b.cpp中是否有定义,只要a.cpp中有b.cpp的类型声明就可以。
那现在呢,考虑模板
模板不是类或者函数,其实就是一个规范,或者说明(用来描述如何生成类或者函数),所以在使用模板时,还有一个生成
模板对应类型的问题, 什么时候生成模板对用的类型或者函数,
1. 比如指针sc,它其实与类型无关,只与cpu寻址范围有关,所以不需要生成类型  //(d) Stack<char> *sc;
2. 引用呢,只是一个别名,生成类型是被引用一方(rsd)的事情, //Stack<double> &rsd
3. 再说函数声明中型参使用的模板,这个函数的声明这是表明在本文见中可以使用f1, 模板的实例化其实在f1的定义的时候 //(a) void f1(Stack<char>);
2017-06-19 11:43
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9032
专家分:54061
注 册:2011-1-18
收藏
得分:0 
void f1(Stack<char>);                   // (a) 这是个函数声明,编译器只要知道 Stack<char> 是个类型就行了,是个什么行为的类型编译器不需要知道

class Exercise {
    Stack<double> &rsd;                 // (b) 引用 和 指针 是一样的,这里存的是个指针,它也不需要知道 Stack<char> 具体是什么行为。
    Stack<int>    si;                   // (c) 这里就需要知道 Stack<int> 有多大,否则就不知道Exercise的内存布局。因为只需要知道 Stack<int> 有多大,所以编译器只需要知道 Stack<int> 有那些成员变量。
};

int main() {
    Stack<char> *sc;                    // (d) 指针,同上
    f1(*sc);                            // (e) 这里会发生拷贝构造,自然需要知道 拷贝构造函数 是个啥。
    int iObj = sizeof(Stack< string >); // (f) 这里需要知道 Stack<int> 有多大,所以编译器只需要知道 Stack<int> 有那些成员变量。
}
2017-06-19 16:14
快速回复:模板函数/模板类实例化问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025422 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved