给定一个具有类似成员模板函数的类:
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 ++中使用成员模板函数,我们使用成员模板函数的情况是什么?
答案 0 :(得分: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;
};
答案 1 :(得分: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函数也可以通用化,产生一个包含2个函数的代码库,其中有12个函数。这样可以通过更简单的运行部件,更易于理解和维护来改进代码。
答案 2 :(得分:3)
成员函数模板的一般用途和功能与普通(非成员)函数模板没有任何不同。唯一[不相关]的区别是成员函数可以访问隐式this
参数。
您了解普通功能模板的一般用途,是吗?那么,在这种情况下,您应该了解成员函数模板的一般用途,因为它完全相同。
答案 3 :(得分:1)
使用您提供的示例,成员模板功能允许您从complex<T>
构建complex<U>
的实例。
作为这可能有用的具体示例,假设您有一个complex<double>
但想要complex<float>
。如果没有构造函数,则类型不相关,因此常规复制构造函数不起作用。
答案 4 :(得分:0)
通常,您希望班级的某些成员函数在某个范围内运行。通过模板化的成员函数,您可以在不提供自由功能的情况下独立于提供范围的容器进行操作。
Functors也是如此。通常你会编写一个函数来运行一些特殊的迭代器,但很快就会发现Functor可以在任何类型的范围内运行。因此,不是通过封装结构提供模板参数,而是通过成员函数operator()提供它们,并使类型推导成为可能。
答案 5 :(得分:0)
首先想到的例子:
在一些容器构造函数(或赋值方法)中获取未知类型的输入迭代器。
std::complex
允许操作不同于std::complex
实例化的类型。
在shared_ptr
中(无论std::tr1::
还是boost::
),以便您可以将不同类型的指针保存到堆中的共享对象实例中(指针类型可以为获得)。
在thread
中(无论是{c} 0x中的std::
还是boost::
)来接收将由线程实例调用的未知类型的仿函数。
在所有情况下,用法都是相同的:您有一个对未知类型进行操作的函数。正如AndreyT完美陈述与常规函数相同。