你能做一个 C++ 泛型函数吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10579022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can you make a C++ generic function?
提问by SGE
Is it possible to create a generic C++ function foo
?
是否可以创建一个通用的 C++ 函数foo
?
foo(Object bar, Object fred)
{
//code
}
in which that if the two objects are recognized, they are compared and a comparison value is returned otherwise some other value is returned to indicate a comparison was not possible?
其中,如果识别出两个对象,则将它们进行比较并返回一个比较值,否则返回某个其他值以指示无法进行比较?
I ask in the case of genericizing a sorting class, in which case you can use this method, and when you derive new objects you want to sort, you add to this foo function, a method on which to sort the new type of Object.
我问在泛化排序类的情况下,在这种情况下您可以使用此方法,并且当您派生要排序的新对象时,您将添加到此 foo 函数中,该方法用于对新类型的对象进行排序。
回答by Peter Wood
Using templates, define two versions of the function, one where the parameters are the same type and one where they can be different:
使用模板,定义函数的两种版本,一种是参数类型相同,另一种是参数可以不同:
#include <string>
#include <iostream>
using namespace std;
template<typename Type>
void func(Type, Type)
{
cout << "same" << endl;
}
template<typename TypeA, typename TypeO>
void func(TypeA, TypeO)
{
cout << "different" << endl;
}
int main()
{
func(5, 3); // same
func(5, 3.0); // different
func(string("hello"), "hello"); // different
func(5.0, 3.0); // same
return 0;
}
输出:
same
different
different
same
回答by Alok Save
回答by mohaps
template<class Type1, class Type2>
void foo(Type1 t1, Type2 t2)
{
// put code here for function
}
call as
称为
foo<std::string, int> ("hello", 10);
回答by bobah
Most probably you need to use templates as other people suggest:
您很可能需要像其他人建议的那样使用模板:
template <class T>
return_type func(T const& l, T const& r)
{
...
}
Because you normally want compilation to fail when the operation implemented by a generic function does not make sense for particular types, so you would either use conditional definition (in the below example is_arithmetic):
因为当泛型函数实现的操作对特定类型没有意义时,您通常希望编译失败,所以您可以使用条件定义(在下面的示例中为 is_arithmetic):
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
template <class T>
typename boost::enable_if<boost::is_arithmetic<T>, return_type>::type
func(T const& l, T const& r)
{
...
}
or static assertion in the code to yield the same result:
或代码中的静态断言以产生相同的结果:
#include <boost/type_traits/is_arithmetic.hpp>
template <class T>
return_type func(T const& l, T const& r)
{
static_assert(boost::is_arithmetic<T>::type::value, "incompatible types");
...
}
回答by Component 10
I'm going to stick my neck out here and say you don't needTemplates to do this. I'm not saying don't use them, but just that depending on exactly what you're wanting to do, there are alternatives.
我将在这里伸出我的脖子说你不需要模板来做到这一点。我并不是说不要使用它们,只是根据您想要做什么,还有其他选择。
What it soundslike you want is the ability to compare two generic objects provided that they adhere to a common set of ground rules. You could actually implement this using traditional inheritance or using templates. The choice of which you want comes down to how flexible you need it to be and whether you want some of the decisions to be made at runtime or compile time. If the latter - i.e. you want to pick up on casting errors etc., - then go for templates.
它听起来像你想的比较,只要它们遵守一套共同的基本规则两个通用对象的能力。您实际上可以使用传统继承或使用模板来实现这一点。您想要的选择取决于您需要它的灵活性以及您是否希望在运行时或编译时做出某些决定。如果是后者——即你想了解铸造错误等,那么就去寻找模板。
Either way, your objects will either have to adhere to some basic groundrules for how you compare them and preferably encapsulate that - this way your comparitor would be generic. or you'd have to write different comparitors for each object comparison. While it sounds like the latter is what you want, be wary of letting too much of your class implementation leach out into the comparitor function and thereby breaking encapsulation.
无论哪种方式,您的对象要么必须遵守一些基本的基本规则来比较它们,并且最好将其封装起来——这样您的比较器将是通用的。或者您必须为每个对象比较编写不同的比较器。虽然听起来后者是您想要的,但请注意不要让过多的类实现渗漏到比较器函数中,从而破坏封装。
From my own experience, going straight to the template approach can occasionally result in a lot of bloated, messed up code which is hard to read, debug and maintain. Take a hard look at you design and what you actually need first.
根据我自己的经验,直接采用模板方法有时会导致大量臃肿、混乱的代码,这些代码难以阅读、调试和维护。首先仔细看看你的设计和你真正需要的东西。
回答by Rollie
OP seems to want to know if the 2 objects are comparable or not. You can use template specialization to achieve this (note: this doesn't compile on VC 10, but does on g++ 4.7). The only nuance, is you want this function to
OP 似乎想知道这两个对象是否具有可比性。您可以使用模板专业化来实现这一点(注意:这不能在 VC 10 上编译,但可以在 g++ 4.7 上编译)。唯一的细微差别是您希望此功能
they are compared and a comparison value is returned otherwise some other value is returned to indicate a comparison was not possible
它们进行比较并返回一个比较值,否则返回一些其他值以指示无法进行比较
But you need to define some sort of structure to signify that a comparison was not possible; using a magic number '-500' or whatever is not good style. Alternately, you could throw an error, and allow it to be caught an handled.
但是您需要定义某种结构来表示无法进行比较;使用一个神奇的数字“-500”或任何不好的风格。或者,您可以抛出一个错误,并允许它被捕获并处理。
struct NoCompare{};
template <typename U1, typename U2>
static auto compare2(const U1 & u1, const U2 & u2) -> decltype(u1 == u2)
{
cout << "Comparable" << endl;
return u1 == u2;
}
static int compare2(...)
{
// Comparison not supported - return whatever value you want. (change the return type as appropriate)
cout << "Not comparable" << endl;
return -500;
}
int main()
{
int a = 5, b = 3, c = 3;
NoCompare dns;
cout << compare2(a, b) << endl;
cout << compare2(dns, b) << endl;
cout << compare2(c, b) << endl;
return 0;
}
Output: C:\MinGW\MinGW>a Comparable 0 Not comparable -500 Comparable 1
输出:C:\MinGW\MinGW>a Comparable 0 不可比较 -500 Comparable 1
回答by nyrtZi
It seems that you are referring to Common Lisp / CLOS -style generic functions which do multiple dynamic dispatch. C++ does single dynamic dispatch with methods but only single static dispatch with functions. So the answer is no. C++ doesn't support this at the moment. There have been proposals along the years to add it into the language but that hasn't happened yet.
您似乎指的是执行多个动态调度的 Common Lisp / CLOS 风格的通用函数。C++ 使用方法进行单一动态调度,但仅使用函数进行单一静态调度。所以答案是否定的。C++ 目前不支持这个。多年来一直有人提议将其添加到语言中,但这还没有发生。