[英]Using Templates to determine function to call
Let's assume, that a class can use the following data-types to pass data to and from it: 假设一个类可以使用以下数据类型来回传递数据:
std::vector<complex> // where "complex" is a struct
and
std::vector DOUBLE or INT or FLOAT or STRING
If the user passes through a std::vector<double>
this implies that a calculation has already been carried out and therefore only a small process has to be completed. 如果用户经过
std::vector<double>
则意味着已经进行了计算,因此只需完成一个很小的过程即可。 If the user, however, passes through std::vector<complex>
this means that the calculation has to be carried out. 但是,如果用户通过
std::vector<complex>
则意味着必须执行计算。
In a class I can do the following: 在课堂上,我可以执行以下操作:
class Foo {
template<typename T>
Foo(T begin, T end)
{
this->transform(begin, end);
}
template<typename T>
void transform(T begin, T end)
{
std::cout << "This has been called";
}
};
But this will have to still invoke me having to have a data member
of one specific type and always assume they are doing that. 但是,这仍然必须使我不得不拥有一种特定类型的
data member
,并始终假设他们正在这样做。
For example, is it possible to override the function transform
for 2 different cases, and, have the constructor decide which method to call depending on type of data being passed to the constructor. 例如,是否有可能在2种不同情况下覆盖函数
transform
,并让构造函数根据传递给构造函数的数据类型来决定要调用的方法。
It would work something like this: 它会像这样工作:
int main()
{
std::vector<double> vals = {1,1,1,1,1,1,1,1};
Foo(std::begin(vals), std::end(vals)); // this will call the method that handles dbls
std::vector<complex> vals = {};
Foo(std::begin(vals), std::end(vals)); // This will call the method that handles complex numbers
}
I hope this makes sense 我希望这是有道理的
This can be solved through template specialization . 这可以通过模板专门化解决。
Considere the following function: 考虑以下功能:
template<typename T>
void Foo(T arg)
{
std::cout << "General" << std::endl;
}
We can now specialize this function for char
types, this means providing another implementation for those types: 现在,我们可以将此功能专用于
char
类型,这意味着为这些类型提供另一种实现:
template<>
void Foo(char arg)
{
std::cout << arg << std::endl;
}
Notice that the template<>
can be omitted in this case. 注意,在这种情况下可以省略
template<>
。
If we now call our functions like this: 如果我们现在这样调用函数:
Foo(1);
Foo('a');
The output will be: 输出将是:
General
a
One way would be tag dispatching (I used struct X instead of complex
here): 一种方法是标记分派(我在这里使用struct X而不是
complex
):
#include <iostream>
#include <vector>
#include <iterator>
struct X {};
struct Foo {
template<typename T>
Foo(T begin, T end)
{
transform(begin, end, typename std::iterator_traits<T>::value_type());
}
template<typename T, typename U>
void transform(T begin, T end, U) // third parameter is unused and serves as a tag
{
std::cout << "floating point\n";
}
template<typename T>
void transform(T begin, T end, X) // same here
{
std::cout << "X\n";
}
};
int main()
{
std::vector<double> v1 = {1,1,1,1,1,1,1,1};
Foo(std::begin(v1), std::end(v1)); // floating point
std::vector<X> v2 = {};
Foo(std::begin(v2), std::end(v2)); // X
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.