Can you make a C++ generic function?

2019-03-19 08:32发布

Is it possible to create a generic C++ function 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.

7条回答
Juvenile、少年°
2楼-- · 2019-03-19 08:33

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;
}

Output:

same
different
different
same
查看更多
▲ chillily
3楼-- · 2019-03-19 08:38

I'm going to stick my neck out here and say you don't need Templates 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 sounds like 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.

查看更多
等我变得足够好
4楼-- · 2019-03-19 08:39
template<class Type1, class Type2>
void foo(Type1 t1, Type2 t2)
{
   // put code here for function
}

call as

foo<std::string, int> ("hello", 10);
查看更多
手持菜刀,她持情操
5楼-- · 2019-03-19 08:42

I think you are in dire need of Templates!
You can write a template function and then write a specialization for the said types to do something specific if the need be.

查看更多
爷的心禁止访问
6楼-- · 2019-03-19 08:43

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.

查看更多
Emotional °昔
7楼-- · 2019-03-19 08:46

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):

#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");
    ...
}
查看更多
登录 后发表回答