2009-04-28 78 views
4

我是C++模板的新手,并且发现很难理解和调试它们。做这两件事有什么好的资源?C++模板的资源

+0

他们很简单。给我们一个你不明白的代码,我们会试着弄清楚它们。 – User 2009-04-28 12:14:50

+0

你能更具体吗?你需要了解他们什么,以及你不了解什么? – jalf 2009-04-28 12:18:46

+0

你有什么材料阅读和理解?有很多很好的书籍和在线文本解释模板。 – 2009-04-28 12:19:54

回答

1

模板只是一种减少开发类时需要编写的代码量的方法。

例如,STL向量

std::vector<int> intList; 
std::vector<float> floatList; 

这将导致编译器实际上使场景,类似于如果您复制并粘贴代码,但替换所有引用与浮动为int落后两班。

如果没有模板,您需要为每个要处理的类型创建一个矢量类。类有更复杂的用途,但这是最容易使用的,可以理解为&。

编译完成后,两组代码vector<int>vector<float>是完全分开的,但IDE在调试时会遍历模板类。

0

他们在那里让您根据需要进行扩展和修改。请记住,这是一个模板,而不是解决方案。

HTH

4

Alexandrescu是模板的向导。他有很多写作(其中许多可以在他的网站和其他网站上免费获得)以及一些书籍。

提升DocumentationBoost Cookbook是一个很好的网站,一旦你对模板感到满意并且觉得自己像毕业后能够升级一样。

1

我有两个快速提示,可以在未来为您节省一些问题。

模板必须定义和接头连接器实现的,因为他们被翻译/在编译时

创建如果你有下面的代码:

// Foo.h 
template <typename T> 
class Foo 
{ 
    ... 
}; 

// Bar.cpp 
#include "Foo.h" 
void func() 
{ 
    Foo<int> fooInt; 
    Foo<double> fooDouble; 
} 

当处理Bar.cpp文件,编译器将创建一个Foo类的新定义,其中每个T都替换为fooInt实例的int类型,并且每个T的一个新定义与每个T替换为fooDouble实例的双重类型。

简而言之,C++不支持模板类,编译器模拟它们在编译时替换类型并创建普通类。所以,fooInt和fooDouble的编译类型是不同的。

因为它们是在编译时翻译的,并且不是单独编译的,所以它们必须在头文件中定义和实现必须

如果将模板类作为普通类(头文件和源文件)实现,编译器(实际上是链接器)抛出的错误是没有实现方法(这是因为源文件被忽略)。

仍然可以创建前置声明,以避免循环依赖

这只是你要转发声明它们是这样的:

template <typename T> 
class Foo; 

而且,与正常的正向声明,你必须请确保您包含所有必要的标题。

-1

这是了解℃的非常好,几乎简练的文章++模板
http://www.codeproject.com/Articles/257589/An-Idiots-Guide-to-Cplusplus-Templates-Part

我会在这里把基本部分:

1.功能模板:

简单的功能模板:

template<class TYPE> 
void PrintTwice(TYPE data) 
{ 
    cout<<"Twice: " << data * 2 << endl; 
} 

注意“TYPE”可以是任何其他有效的名字。

您应该更好地使用反映类型参数含义的名称,并且该名称可以提高代码的可读性。

现在你可以这样调用:

PrintTwice(5.5);//TYPE is 'float' 
PrintTwice(5);//TYPE is 'int' 

可以强制编译器实例化功能类型传递明确:

PrintTwice<double>(5); 

,如果你不及格任何类型的编译器都会确定类型是什么。

你可以有多个参数模板和(可选)返回类型相同类型:

template<class T> 
T Add(T n1, T n2) 
{ 
    return n1 + n2; 
} 

但请注意,你不能例如通过在intn2n1双!两个参数应该是相同的类型,并且返回类型也是该类型的。

如果你想有可能是不同的类型参数的模板函数:

template<class T1, class T2> 
double Add(T1 t1Data, T2 t2Data) 
{ 
    return t1Data + t2Data; 
} 

,并用它喜欢:

cout<<Add(5,7.0);//T1=int T2=double 
cout<<Add(5.5,7);//T1=double T2=int 
cout<<Add<double,double>(5,7);//T1=double T2=double by passing types explicitly 

当函数模板采用模板式,而不是从它的函数参数如:

template<class T> 
void PrintSize() 
{ 
    cout << "Size of this type:" << sizeof(T); 
} 

您不能简单地调用这样的函数模板:

PrintSize(); 

由于此函数模板需要模板类型参数说明,并且它不能由编译器自动推导出来。正确的调用是:

PrintSize<float>(); 

2.class模板:

定义几乎是相似的:

template<class T> 
class Item 
{ 
    T Data; 
public: 
    Item() : Data(T()) 
    {} 

    void SetData(T nValue) 
    { 
     Data = nValue; 
    } 

    T GetData() const 
    { 
     return Data; 
    } 

    void PrintData() 
    { 
     cout << Data; 
    } 
}; 

,但使用它时,你应该明确地指定类型:

Item<int> item1; 

棘手的部分是,你不能imp字元素声明在头文件,并在一个或多个源文件相应的执行(请参考文章,看看为什么)

类模板也让一些非类型模板参数:

template<class T, int SIZE> 
class Array 
{ 
static const int Elements_2x = SIZE * 2; 
void DoSomething(int arg = SIZE); 
// Non-const can also appear as default-argument... 
private: 
    T TheArray[SIZE]; 
}; 

有还有很多其他的部分和更多的解释,我不能带到这里。

我建议你花几个小时阅读那篇文章和那篇文章的第二部分。即使你认为你知道模板在C++中的工作方式。

+1

这可能在理论上回答这个问题,但最好将答案的基本部分包括在内以供将来的用户使用并提供链接供参考。 [link-dominated answers](// meta.stackexchange.com/questions/8231)可能通过[link rot](// en.wikipedia.org/wiki/Link_rot)失效。 – Mogsdad 2016-02-25 18:50:08

+1

最好不要回答离题问题,例如请求离线资源。 – TylerH 2016-02-25 18:51:08