简体   繁体   中英

bind non static templated member function in derived class

#include <functional>
#include <iostream>

class Plain {
   public:
    template <typename Type>
    void member_function(const Type& s) {
        std::cout << "Recived: " << s << std::endl;
    }
};

template <typename Type>
class Templated : private Plain {
   public:
};

int main() {
    Plain b;
    b.member_function<int>(10); // done!
    Templated<int> d;
    // d.member_function();  /* how to achive this */

    return 0;
}

I am trying to call the member function in class Plain by two method:

  1. createing non-templated class and padding type while calling function
Plain p;
p.member_function<int>();
  1. passing type while creating class and calling without template param
Templated<int> t;
t.member_function(); // achive this

I tried doing binding the function in derived class like

struct Plain{
    template<typename T>
    static void member_function(const T& s){std::cout << s << std::endl;}
}

template<typename T>
struct Templated : private Plain {
    std::function<void(const T&)> print = Templated::Plain::member_function;
}

and after that I was able to do

Templated t<std::string>;
t.print();

When you use private inheritance the methods in Plain are inaccessible to outside code, and you need to have something inside of Templated make the call to the method in Plain; you can do so, or alternatively you could use public inheritance and be able to hit it directly.

class Plain {
public:
    template <typename T>
    void print(const T & s) {
        std::cout << "Received: " << s << std::endl;
    }
};

template <typename T>
class Templated : private Plain {
public:
    void print(const T & s) {
        Plain::print<T>(s);
    }
};

template <typename T>
class Alternative : public Plain {};

int main() {
    Templated<int> t;
    t.print(3); // This could work

    Alternative<int> a;
    a.print(4); // As could this

    return 0;
}

I found a workaround

#include <functional>
#include <iostream>
using namespace std::placeholders;

struct Test {
    template <typename Type>
    void foo(const Type&) {
        std::cout << "I am just a foo..." << std::endl;
        return;
    }
};

template <typename T>
struct Foo {
   private:
    Test* obj;

   public:
    Foo() : obj(new Test) {}
    std::function<void(const int&)> foo = std::bind(&Test::foo<T>, obj, _1);
    ~Foo() { delete obj; }
};

int main() {
    Foo<int> me;
    me.foo(10);

    Test t;
    t.foo<int>(89);

    std::cout << std::endl;
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM