template
template的声明与原代码分开在vc下为什么不能link? 问题点数:100、回复次数:4Top
1 楼SlaSk(七叔)回复于 2002-03-29 21:10:49 得分 0
VC对标准支持不完全产生的问题。
还有在类内如此也不可以,标准是允许的。
const static int xxx;Top
2 楼Nhsoft(我不是高手)回复于 2002-03-29 21:29:16 得分 0
这是M$的缺点,以前 Bjarne 就说有一个大公司反对Template 那就是M$
他的template最差了
你用GNU的或Borland的绝对没有问题Top
3 楼joy8223(COM)回复于 2002-03-29 22:03:25 得分 0
编译器的问题,我也碰过类似的问题,你把他们写在一起就行了Top
4 楼prototype(原型)回复于 2002-03-30 07:19:18 得分 100
这是 ***not*** M$的缺点.
all current c++ compilers don't support the seperation of
the template implementation from its declaration.
reason? read this:
[31.11] Why can't I separate the definition of my templates class from it's declaration and
put it inside a .cpp file?
[Recently created thanks to Assaf Lavie (in 3/02). Click here to go to the next FAQ in the "chain" of recent changes.]
In order to understand why things are the way they are, you must accept a few facts:
1.A template is not a class or a function. A template is a "pattern" that the compiler uses to generate a family of classes or
functions.
2.In order for the compiler to generate the code, it must see both the template definition (not just declaration) and the specific
types/whatever used to "fill in" the template. For example, if you're trying to use a Foo<int>, the compiler must see both the
Foo template and the fact that you're trying to make a specific Foo<int>.
3.Your compiler probably doesn't remember the details of one .cpp file while it is compiling another .cpp file. It could, but
most do not and if you are reading this FAQ, it almost definitely does not. BTW this is called the "separate compilation
model."
Now assuming you accept those facts, let's work an example to show why things are the way they are. Suppose you have a template
Foo defined like this:
template<class T>
class Foo {
public:
Foo();
void someMethod(T x);
private:
T x;
};
Along with similar definitions for the member functions:
template<class T>
Foo<T>::Foo()
{
...
}
template<class T>
void Foo<T>::someMethod(T x)
{
...
}
Now suppose you have some code in file Bar.cpp that uses Foo<int>:
// Bar.cpp
void blah_blah_blah()
{
...
Foo<int> f;
f.someMethod(5);
...
}
Clearly somebody somewhere is going to have to use the "pattern" for the constructor definition and for the someMethod()
definition and instantiate those when T is actually int. But if you had put the definition of the constructor and someMethod()
into file Foo.cpp, the compiler would see the template code when it compiled Foo.cpp and it would see Foo<int> when it
compiled Bar.cpp, but there would never be a time when it saw both the template code and Foo<int>. So by rule #2 above, it
could never generate the code for Foo<int>::someMethod().
The simplest approach to this is to add the definitions for all the methods (not just the inline methods) in Foo.hpp. There are
other approaches as well, and some of these other approaches result in smaller executables at the expense of a little ease-of-use.
A note to the experts: I have obviously made several simplifications above. This was intentional so please don't complain too loudly.
For example, if you know enough to complain about my simplifications (e.g., if you know the difference between a .cpp file and a
compilation unit, the difference between a class template and a template class, and the fact that templates really aren't just glorified
macros), then you didn't need to read this answer in the first place - this particular question/answer wasn't aimed at you. Bottom
line: I simplified things so newbies would "get it," even if doing so offends some experts.
Top




