【问题标题】:bind non static templated member function in derived class在派生类中绑定非静态模板化成员函数
【发布时间】:2020-07-07 12:58:23
【问题描述】:
#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;
}

我正在尝试通过两种方法调用class Plain 中的成员函数:

  1. 在调用函数时创建非模板类和填充类型
Plain p;
p.member_function<int>();
  1. 在创建类时传递类型并在没有模板参数的情况下调用
Templated<int> t;
t.member_function(); // achive this

我尝试在派生类中绑定函数,例如

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

然后我就可以了

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

【问题讨论】:

  • 我不确定我是否理解。你想让d.member_function();做什么?我了解您想要此模板的 int 版本,但您没有将所需的参数传递给它。另外,您显示的print 版本似乎不起作用。
  • 不能调用函数模板;需要实例化,只有编译器能够推导出模板参数,才能自动实例化。而且你不能在不传递这些参数的情况下调用一个接受参数的函数,所以不清楚你为什么期望能够实现这一点。

标签: c++ function templates binding class-hierarchy


【解决方案1】:

当您使用私有继承时,Plain 中的方法无法被外部代码访问,您需要在 Templated 内部有一些东西来调用 Plain 中的方法;你可以这样做,或者你可以使用公共继承并能够直接命中它。

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

【讨论】:

  • 虽然此方法有效,但如果我无法访问基类的源代码怎么办
  • @Dev-il 比如当你在头文件(.h)中声明了plain和方法,但方法的定义在源文件(.cpp)中?跨度>
  • 不,我的意思是 Base 类是否已编译或位于库中。当我没有源代码时,类似的东西。
  • 如果基类是在一个库中定义的,那么你应该有一个包含基类声明和方法的头文件;否则我不确定你将如何继承它;通常库会在标头中包含模板化方法的方法体(这样您实际上就拥有源代码),如果它们没有,那么您只能使用它们在其库中显式实例化的模板参数调用模板化方法例如github.com/jjf28/Chkdraft/blob/master/MappingCoreLib/…
【解决方案2】:

我找到了解决方法

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

【讨论】:

  • 这正是我想要的
猜你喜欢
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
  • 2013-05-30
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
相关资源
最近更新 更多