Can you make a C++ generic function?

前端 未结 7 1293
轮回少年
轮回少年 2021-02-07 18:03

Is it possible to create a generic C++ function foo?

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

in which that if the two objects

相关标签:
7条回答
  • 2021-02-07 18:40

    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.

    0 讨论(0)
  • 2021-02-07 18:51

    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.

    0 讨论(0)
  • 2021-02-07 18:54

    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

    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.

    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

    0 讨论(0)
  • 2021-02-07 19:04

    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
    
    0 讨论(0)
  • 2021-02-07 19:05

    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.

    0 讨论(0)
  • 2021-02-07 19:07
    template<class Type1, class Type2>
    void foo(Type1 t1, Type2 t2)
    {
       // put code here for function
    }
    

    call as

    foo<std::string, int> ("hello", 10);
    
    0 讨论(0)
提交回复
热议问题