转自: http://www.codeproject.com/KB/cpp/templatesourceorg.asp 

Introduction

Often I get asked whether programming with templates is hard or easy. The answer I usually give is: "It is easy to use templates, but it is hard to make them". Just take a look at some template libraries that we use in our everyday programming, like STL, ATL, WTL, some libraries from Boost, and you will see what I mean by this. Those libraries are great example of the principle "simple interface - complex implementation".

I started using templates five years ago when I discovered MFC template containers, and until last year I had no need to develop them myself. When I finally got to the point that I needed to develop some template classes, the first thing that hit me was the fact that the "traditional" way of organizing source code (declarations in *.h files, and definitions in *.cpp files) does not work with templates. It took me some time to understand why this is the case, and how to work around this problem.

This article is aimed at developers who understand templates well enough to use them, but are not very experienced at developing them. Here, I will cover only template classes and not template functions, but the principles are the same in both cases.

The Problem Described

To illustrate the problem, we will use an example. Suppose we have a template class array (nothing to do with boost::array template class) in a file array.h.

代码
// array.h

template 
<typename T, int SIZE>
class array
{
    T data_[SIZE];
    array (
const array& other);
    
const array& operator = (const array& other);
public:
    array(){};
    T
& operator[](int i) {return data_[i];}
    
const T& get_elem (int i) const {return data_[i];}
    
void set_elem(int i, const T& value) {data_[i] = value;}
    
operator T*() {return data_;}      
};

Also, we have a file main.cpp in which is the code that uses array:

// main.cpp

#include 
"array.h"


int main(void)
{
array
<int50> intArray;
intArray.set_elem(
02);
int firstElem = intArray.get_elem(0);
int* begin = intArray;
}

 

This compiles fine, and does exactly what we want: first we make an array of 50 integers, then set the first element to be 2, read the first element, and finally take the pointer to the beginning of the array.

Now, what happens if we try to organize the code in more traditional way? Let's try to split the code in array.h and see what happens. Now we have two files: array.h and array.cpp (main.cpp remains unchanged).

 

代码
// array.h        

template 
<typename T, int SIZE>
class array
{
      T data_[SIZE];
      array (
const array& other);
      
const array& operator = (const array& other);
  
public:
      array(){};
      T
& operator[](int i);
      
const T& get_elem (int i) const;
      
void set_elem(int i, const T& value);
      
operator T*();      
};        

// array.cpp

#include 
"array.h"


template
<typename T, int SIZE> 
       T
& array<T, SIZE>::operator [](int i)
    {
    
return data_[i];
    }

template
<typename T, int SIZE> 
       
const T& array<T, SIZE>::get_elem(int i) const
    {
    
return data_[i];
    }

template
<typename T, int SIZE> 
       
void array<T, SIZE>::set_elem(int i, const T& value)
    {
    data_[i] 
= value;
    }
template
<typename T, int SIZE> array<T, SIZE>::operator T*()
    {
    
return data_;
    }

相关文章:

猜你喜欢
相关资源
相似解决方案