你能做一个C ++泛型函数吗?

时间:2012-05-14 07:21:04

标签: c++ oop generics sorting object

是否可以创建通用C ++函数foo

foo(Object bar, Object fred)
{
    //code
}

其中如果识别出两个对象,则比较它们并返回比较值,否则返回一些其他值以表示无法进行比较?

我要求对泛化类进行泛化,在这种情况下你可以使用这个方法,当你派生出你想要排序的新对象时,你可以添加到这个foo函数,一个对新类型进行排序的方法对象。

7 个答案:

答案 0 :(得分:25)

使用模板,定义两个版本的函数,一个参数类型相同,另一个版本可以不同:

#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

答案 1 :(得分:18)

我认为你迫切需要 Templates ! 您可以编写模板函数,然后为所述类型编写特殊化,以便在需要时执行特定操作。

答案 2 :(得分:5)

template<class Type1, class Type2>
void foo(Type1 t1, Type2 t2)
{
   // put code here for function
}

打电话给

foo<std::string, int> ("hello", 10);

答案 3 :(得分:3)

很可能你需要像其他人建议的那样使用模板:

template <class T>
return_type func(T const& l, T const& r)
{
   ...
}

因为当通用函数实现的操作对特定类型没有意义时,通常希望编译失败,所以你要么使用条件定义(在下面的例子中是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)
{
    ...
}

或代码中的静态断言产生相同的结果:

#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");
    ...
}

答案 4 :(得分:1)

我要把我的脖子伸到这里说你不需要模板来做这件事。我不是说不要使用它们,而只是根据你想要做的事情,有其他选择。

它想要的声音是能够比较两个通用对象,只要它们符合一组通用的基本规则。您实际上可以使用传统继承或使用模板来实现此功能。您想要的选择取决于您需要它的灵活性,以及​​您是否希望在运行时或编译时做出一些决策。如果后者 - 即你想要了解投射错误等,那么 - 去模板。

无论哪种方式,您的对象要么必须遵守一些基本的基本规则,以便比较它们,并且最好将其封装 - 这样您的比较器将是通用的。或者你必须为每个对象比较编写不同的比较器。虽然听起来后者就是你想要的,但要注意让你的类实现过多地渗透到比较器函数中,从而打破封装。

根据我自己的经验,直接使用模板方法有时会导致很多臃肿,混乱的代码难以阅读,调试和维护。仔细看看你的设计以及你真正需要的东西。

答案 5 :(得分:0)

OP似乎想知道2个对象是否具有可比性。您可以使用模板专门化来实现这一点(注意:这不能在VC 10上编译,但在g ++ 4.7上编译)。唯一的细微差别,就是你想要这个功能

  

比较它们并返回比较值,否则返回一些其他值以表示无法进行比较

但是你需要定义某种结构来表示不可能进行比较;使用幻数'-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;
}

输出: C:\ MinGW的\ MinGW的&gt;一种 可比 0 没有可比性 -500 可比 1

答案 6 :(得分:0)

您似乎指的是Common Lisp / CLOS风格的泛型函数,它们执行多个动态调度。 C ++使用方法进行单个动态调度,但只使用带有函数的单个静态调度。所以答案是否定的。 C ++目前不支持此功能。多年来一直有人建议将其添加到语言中但尚未发生。