Как получить шаблонный класс C ++ для вызова методов другого класса? - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть класс A, который должен вызывать функции-члены шаблона класса B. Поиск по сайту Я нашел этот пример кода на этом сайте:

#include <iostream>

template<typename T, typename FType>
void bar(T& d, FType f) {
  (d.*f)(); // call member function
}

struct foible
{
  void say()
  {
    std::cout << "foible::say" << std::endl;
  }
};

int main(void)
{
  foible f;
  bar(f,  &foible::say); // types will be deduced automagically...
}

Это пришло из этого ответа: Метод C ++имя в качестве параметра шаблона

Но это не делает 100% того, что мне нужно.Как переписать приведенный выше код так, чтобы:

  1. метод bar был открытым членом класса, а не отдельной функцией
  2. arguments d иf, которые передаются методу bar, являются public членами того же класса, к которому bar является членом, что позволяет bar иметь тип void (void)
  3. тип объекта foible является классом, а не структурой (необязательно)?

[РЕДАКТИРОВАТЬ 1] Моя собственная попытка перезаписи, которая соответствует пунктам 1) и 2), заключается в следующем, что неверно:

#include <iostream>

template<class T, void (T::*FType)()>
class foo {
public:
  T obj;
  FType f;
void bar(void) {
  (obj.*f)(); // call member function
} // end bar
}; // end class foo

struct foible
{
  void say()
{
  std::cout << "foible::say" << std::endl;
}
};

int main(void)
{
foible f;
foo<foible, void (foible::*)()> c;
c.T = f;
c.Ftype = &foible::say;

c.bar(); // types will be deduced automagically...
}

Моя цель состоит в том, чтобы объект типа «A» вызывал методы объекта типа «B», чтобы при выполнении этих методов объект типа «B» мог использовать егоуказатель для ссылки на свои локальные данные.Я хочу использовать указатели на функции внутри класса типа «А», чтобы их нужно было указывать только один раз, и я не хочу, чтобы один класс был производным от другого.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Пошаговое решение: во всех примерах используется следующий класс и функция foo

#include <iostream>
class A
{
public:
    void foo(){std::cout<<"foo"<<std::endl;}
};

этот пример работает без шаблона: просто вызывая вызывающий A :: foo с указателем на A и указателем наA::foo:

class B
{
public:
    A *a;
    void (A::*p)(); 

    void bar()
    {
        (a->*p)(); //call A::foo 
    }
};
int main(void)
{
    A a;
    B b;
    b.a = &a;
    b.p = &A::foo;
    b.bar();
    return 0;
}

В следующем примере добавлен шаблон class T, указатель на метод foo, полученный из T.

template <class T>
class C
{
public:
    T* t;
    void (T::*p)(); 
    C(T &o) : t(&o){} 
    void bar()
    {
        (t->*p)();
    }
};
int main(void)
{
    A a;
    C<A> c(a);
    c.p = &A::foo;
    c.bar();
    return 0;
}

, ниже указатель на метод былтоже шаблонизируется, но я не вижу, как это можно использовать, так как вы должны знать, сколько аргументов дать, но в любом случае:

template <class T, typename F>
class D
{
public:
    T* t;
    F p; 
    D(T &o, F pf) : t(&o),p(pf){} 
    void bar()
    {
        (t->*p)();
    }
};
int main(void)
{
    A a;
    D<A, void (A::*)()> d(a, &A::foo);
    d.bar();
    return 0;
}
0 голосов
/ 20 февраля 2019

Вы делаете это слишком сложным.Забудьте про указатели на методы.В настоящее время нет никаких оснований для их использования.

Просто сделайте что-то вроде этого:

template<typename F>
void bar(F f) {
  doSomething();

  f(someArg);

  doSomething();
}

int main(void)
{
  foible f;
  bar([&f](auto x) { f.someMagicMethod(x); } );

  return 0;
}

Обратите внимание, что этот подход более гибок и удобочитаем, чем работа с указателями методов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...