2010-02-25 58 views
4

鉴于一类像这样的一个成员模板函数:C++中成员模板函数的用法是什么?

template <typename t> 
class complex 
{ 
public: 
    complex(t r, t im); 
    template<typename u> 
    complex(const complex<u>&); 
private: 
    //what would be the type of real and imaginary data members here. 
} 

我感到困惑的成员模板函数,请提供通过其成员模板函数的需求变得清楚,我举一个例子。
另外,告诉我在C++中使用成员模板函数,我们使用成员模板函数的情况是什么?

+1

格式化您的问题并缩进代码时请格外小心。 – avakar 2010-02-25 18:12:23

回答

3

成员函数模板的一般用途和功能与普通(非成员)函数模板没有任何区别。唯一的[不相关的]区别是成员函数可以访问隐含的this参数。

您了解普通函数模板的一般用途吗?那么,在这种情况下,您应该了解成员函数模板的一般用途,因为它完全相同。

+0

谢谢你的回答有帮助 – 2010-02-25 20:14:19

5

它给你做转换的能力:

complex<int> ci; 

complex<float> cf(ci); 

所以,如果你有两个类型T1和T2,你可以一个T1分配到T2,这将有可能为complex<T1>分配给一个complex<T2>

至于在你的代码的问题(这将是实部和虚数据成员,这里的类型):

template <typename t> 
class complex 
{ 
... 
private: 
    t real_part; 
    t imaginary_part; 
}; 
+0

这不是模板成员函数的图示。 – 2010-02-25 18:17:35

+0

请提供一个例子,除了复杂的类,我们需要使用成员模板函数 – 2010-02-25 18:18:52

+0

这不是一个实现,但它是一个例子,给定了提问者的头文件。 – 2010-02-25 18:19:49

1

使用你提供的例子,成员模板函数可以构建的一个实例complex<T> from complex<U>

作为什么时候这可能有用的具体示例,假设您有complex<double>但想要complex<float>。没有构造函数的类型是不相关的,所以常规的拷贝构造函数不起作用。

4

我在日常工作中遇到的成员模板函数最常见的有用用法是通过提供一个模板函数而不是执行基本相同的功能的许多函数来降低代码复杂度。

例如,假设您正在一台服务器上工作,该服务器接收半打相关的消息,并将传入的数据保存到数据库中的半打表中。一个简单的实现将实现6个消息处理函数(psudocode):

class MessageProcessor 
{ 
    void OnMessage(const char* msg); 
    void ProcessMessage100(Data100* data); 
    void ProcessMessage101(Data101* data); 
    void ProcessMessage102(Data102* data); 
    void ProcessMessage103(Data103* data); 
    void ProcessMessage104(Data104* data); 
    void ProcessMessage105(Data105* data); 
}; 

MessageProcessor::OnMessage(const char* msg) 
{ 
    unsigned int * msgType = ((unsigned int*)msg); 
    switch(*msgType) 
    { 
    case 100 : 
     ProcessMessage100((Data100*),sg); 
     break; 
    case 101 : 
     ProcessMessage101((Data101*),sg); 
     break; 
    :: 
    } 
} 

MessageProcessor::ProcessMessage100(Data100* data) 
{ 
    Record100* record = GetRecord100(key); 
    record->SetValue(xyz); 
} 

MessageProcessor::ProcessMessage101(Data101* data) 
{ 
    Record101* record = GetRecord101(key); 
    record->SetValue(xyz); 
} 

: : 

这里有一个机会来概括ProcessMessage的()函数,因为它们基本上做同样的事情:

class MessageProcessor 
{ 
    OnMessage(const char* msg); 

    template<class Record, class Data> void Process(Data* data); 
}; 

template<class Record, class Data> 
void MessageProcessor::Process<Record,Data>(Data* data) 
{ 
    Record* record = GetRecord(key); 
    record->SetValue(xyz); 
} 

GetRecord函数也可以进行通用化处理,产生一个代码库,其中有两个函数,以前的版本是12.这改进了代码,因为它更简单,移动部件更少,更易于理解和维护。

0

通常你会希望你的类的某些成员函数在一个范围上进行操作。通过使用模板化的成员函数,您可以在不提供免费功能的范围内独立于提供范围的容器进行操作。

Functors也是如此。通常你会写一个函子来操作一些特殊的迭代器,但很快就意识到可以让Functor在任何类型的范围上运行。因此,可以通过成员函数操作符()来提供它们,而不是通过封装结构提供模板参数,并使类型推断成为可能。

0

浮现在脑海中的第一个例子:

  • 在一些容器构造(或分配方法)取未知类型的输入迭代。

  • std::complex允许在不同的类型上操作std::complex实例化的类型。

  • shared_ptr(是否std::tr1::boost::),这样就可以保持不同类型的指针到在堆共享对象实例(其可以得到的指针类型)。

  • thread(是否std::在C++ 0x或boost::中)接收将由线程实例调用的未知类型的函子。

在所有情况下,使用情况都是相同的:您有一个功能可以对未知类型进行操作。正如AndreyT完美地表述的那样,以及常规功能。