简体   繁体   English

在C ++库中正确使用模板进行特定的基于类型的优化

[英]Correct use of templates for specific type-based optimization in C++ library

If I have a function that I want to implement for all types but then have specific optimizations for some types, how do I do this correctly in C++ with templates? 如果我有一个我想为所有类型实现的函数,但是对某些类型有特定的优化,我该如何在C ++中使用模板正确地执行此操作?

At the moment, in the header file I have: 目前,在头文件中我有:

template <class T> void Function(const T &src)
{
   printf("something generic to fall back on with src if nothing else fits");
}

void Function(const int &src);
void Function(const float &src);
void Function(const double &src);

Then in the cpp file I have: 然后在cpp文件中我有:

void Function(const int &src) { printf("specialization %d\n", src); }
void Function(const float &src) { printf("specialization %g\n", src); }
void Function(const double &src) { printf("specialization %g\n", src); }

Firstly I wanted to check that I am correct in not putting template<> in front of the declarations in the header file? 首先,我想检查我是否正确将template<>放在头文件中的声明前面? I don't fully understand the use of template with empty brackets. 我不完全理解使用带空括号的template

Now it turns out that I have actually lots of cases of optimized implementations for about 10 different types. 现在事实证明,我实际上已经为大约10种不同类型提供了大量优化实现的案例。 Some of them are almost the same, like the versions for float and double above. 其中一些几乎相同,如floatdouble版本。 Therefore it makes sense if I can template a subset of the specializations that are within the cpp file, but I don't see how to do that. 因此,如果我可以模拟cpp文件中的特化的子集,但我不知道如何做到这一点。 Is the only way to call a separate internal templated function? 是调用单独的内部模板化函数的唯一方法吗?

What I want is a catch all implementation that is generic and is present in the header file which can be include by the application that uses the library, then I want a set of identical templated specializations for a subset of known data types that are exported from the library and implemented in the cpp file, and then finally a set of highly optimized cases for just one or two types that are also in the cpp file. 我想要的是一个catch通用的所有实现,并且存在于头文件中,可以由使用该库的应用程序包含,然后我想要一组相同的模板化特化,用于从中导出的已知数据类型的子集该库并在cpp文件中实现,最后是一组高度优化的案例,仅适用于cpp文件中的一种或两种类型。

How can I best achieve this? 我怎样才能做到最好?

You're 100% right that you don't need the template<> for this. 你是100%正确的,你不需要template<> You only need template when writing a template function, and you aren't writing template function specializations, you're making entirely new functions, that happen to have the same name. 在编写模板函数时,您只需要template ,并且您没有编写模板函数特化,而是在创建全新的函数,这些函数碰巧具有相同的名称。

//template function - templated on any type
template <class T> void Function(const T &src); 
//template function specialization for std::vector, itself takes 2 template params
//(This technically only works with classes, not functions, for unrelated 
// reasons, but it would use this syntax)
template <class U, class A> void Function<std::vector<U,A>>(const std::vector<U,A>& src);
//template function specialization for int, itself takes 0 template params
template<> void Function<int>(const int& src)

//not in any way a template, this is a completely unrelated regular function
void Function(double);

If you have nearly similar functions with different types, that calls 100% for templates! 如果你有几乎不同类型的功能,那么模板调用100%! So use them! 所以使用它们! Note that since this template is only used in a single cpp file, it doesn't need to be in a header. 请注意,由于此模板仅用于单个cpp文件,因此不需要位于标头中。 The template itself can be in the cpp file. 模板本身可以在cpp文件中。 So, in your .cpp file, write this: 因此,在.cpp文件中,写下:

 template<class flttype>
 void FloatFunction(const flttype&src) {
     printf("specialization %g\n", src);
 }

 void Function(const float &src) { FloatFunction(src);}
 void Function(const double &src) { FloatFunction(src);}


You mentioned that these other function with the same name should be template specializations. 您提到这些具有相同名称的其他函数应该是模板特化。 That's not what you're doing, but that's also easy to do. 这不是你在做什么,但这也很容易做到。 In fact, it's surprisingly like regular functions. 事实上,它令人惊讶地像常规功能。 Change your prototypes to these: 将原型更改为:

 template <class T> void Function(const T &src) { printf("something generic to fall back on with src if nothing else fits"); } template<> void Function<int>(const int &src); template<> void Function<float>(const float &src); template<> void Function<double>(const double &src); 

and then change the code in your cpp files to these: 然后将cpp文件中的代码更改为:

 template<> void Function<int>(const int &src) { printf("specialization %d\\n", src); } template<> void Function<float>(const float &src) { printf("specialization %g\\n", src); } template<> void Function<double>(const double &src) { printf("specialization %g\\n", src); } 

You don't need template specialization in your example: Overload resolution takes care of things for you. 您的示例中不需要模板专业化:重载解析为您处理事情。

Remember: When matches would otherwise be equal, non-template functions are preferred during overload resolution over template functions. 请记住:当匹配在其他方面相同时,非模板函数在模板函数的重载解析期间是首选。

Therefore, for int s, the compiler will prefer the overload that explicitly takes an int (ie is not a template) to the one wherein it could deduce T to int and form a template match. 因此,对于int ,编译器将更喜欢显式地将int (即不是模板)的重载转换为可以将T推导为int并形成模板匹配的重载。

To try and clear up your confusion about template <> , you use it when you're declaring a specialized template, and you've specialized away all the template parameters. 要尝试清除对template <>困惑,可以在声明专用模板时使用它,并且已经专门设置了所有模板参数。 You can specialize function templates, but in many (perhaps "most") cases this is unnecessary and overloading (as you've done) is quicker and easier. 您可以专门化功能模板,但在许多(也许是“大多数”)情况下,这是不必要的,并且重载(如您所做)更快更容易。

In your case, however, your non-template functions are not templates at all, so you're not specializing anything, and therefore you don't declare them as templates (empty parameter list or otherwise). 但是,在您的情况下,您的非模板函数根本不是模板,因此您不会专门设置任何内容,因此您不会将它们声明为模板(空参数列表或其他)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM