Is there a generic way to adapt a function template to be a polymorphic function object?

后端 未结 2 815
清歌不尽
清歌不尽 2020-12-14 21:42

I have some function templates, for example

template 
void foo(T);

template 
void bar(T);

// others

a

相关标签:
2条回答
  • 2020-12-14 22:42

    The short version of the problem is given an overloaded name f, how to concisely write an object ff such that ff(a0, a1, a2, ...) ultimately calls f(a0, a1, a2, ...).

    A polymorphic functor, how you point out yourself, is the usual solution. But it must be defined out of line (since it has a template member), so I'll consder that not concise enough for the purposes of my answer.

    Currently lambda expressions yield a monomorphic functor, so they're close but not quite there.

    // set of functions overloaded on int and double
    void f(int);
    void f(double);
    
    auto ff = [](int i) { return f(i); };
    

    As GMan pointed out in the comments polymorphic lambdas would (should?) be the solution to concisely write polymorphic functors inline.

    In the meantime, it is possible to write a make_overload helper that combines multiple functors into one, such that

    auto ff = make_overload(
        [](int arg0) { return f(arg0); }
        , [](double arg0) { return f(arg0); } );
    

    would 'capture' the whole overload set. Perhaps a Boost.Preprocessor macro could help here, so that auto ff = POLYMORPHIC_LAMBDA( 1, (int)(double), { return f(arg0); } ); be used inline. I suspect there are arity restrictions however (hence the first macro argument), unlike the usual out-of-line hand-written polymorphic functor solution; so this wouldn't help with e.g. variadic function templates.

    0 讨论(0)
  • 2020-12-14 22:48

    Why couldn't you use template template parameters? You said you can't pass your template uninstantiated, but I'm not sure if you've heard of this before, tell me if you have and it won't work.

    I don't know what your code structure looks like, but can you do something like

    I know this works, don't know if it's what yo uwant though:

    template<typename T>
    T some_algorithm(T data) { return T(); } // just returning nothing for example
    
    template<typename T, T(*Something)(T)>
    class FuncClass {
    public:
        T run(T data) { return Something(data); }
    };
    
    template<typename T, typename Functor>
    void apply_algorithm(T data) {
        Functor F;
        F.run(data);
    }
    
    int main() {
        int mydata = 4;
        apply_algorithm<int, FuncClass<int, some_algorithm<int> > >(mydata);
    
        cin.get();
    }
    
    0 讨论(0)
提交回复
热议问题