Доступ к переменным-членам с помощью шаблонов - PullRequest
1 голос
/ 26 сентября 2019

Мне нужна функция шаблона, которая может служить общей цели доступа к переменной-члену и рабочим функциям, присутствующим в этой переменной-члене.У меня есть набор функций для вызова, и это решит мою задачу.

Я попробовал следующее

class Utilities {
public:
template<typename Container, typename MemberVar, typename Operator>
static void for_all(Container& C, MemberVar memvar, Operator Op) {
    for (auto& element : C) {
        (element.memvar->Op)();
    }
 }
};

У меня есть следующий код теста, где есть класс Test, который имеет PrivateImplи DataStructure, которая проводит приватизацию.Ниже приведена функция печати, которая вызывает функцию Utilities :: for_all с функцией печати privateimpl

void Test::print() {
    ::Utilities::for_all(m_vec_struct_privateimpl,&Test::Struct_PrivateImpl::m_privateimpl,&Test::CPrivateImpl::print);
}

Ниже приведена подробная информация обо всех классах

// Main Class
class Test {
public:
    Test();
    ~Test();
    void print();
private:
    class CPrivateImpl;
    struct Struct_PrivateImpl;
    std::vector<Struct_PrivateImpl> m_vec_struct_privateimpl;
}; //class Utilities

// Class PrivateImpl
class Test::CPrivateImpl {
public:
    CPrivateImpl(std::initializer_list<int>& lst) {
        for (auto& i : lst) {
            m_vec_int.push_back(i);
        }

    }
    void print(int i) {
        cout << i << " ";
    }
private:
    std::vector<int> m_vec_int;

}; //class Test::CPrivateImpl

// Data Structure having PrivateImpl
struct Test::Struct_PrivateImpl {
public:

    Struct_PrivateImpl(int i) {
        m_privateimpl = std::make_shared<Test::CPrivateImpl>(std::initializer_list<int>{100+i,200+i,300+i});

    };
    ~Struct_PrivateImpl() {
    }

//private:
    std::shared_ptr<CPrivateImpl> m_privateimpl;
}; // class WiperSkeletonSomeIP::Struct_PrivateImpl

Test::Test(){
    for(auto i = 0u; i != 3; ++i) {
        Struct_PrivateImpl a_struct_pvtimpl(i);
        m_vec_struct_privateimpl.push_back(a_struct_pvtimpl);
    }
}
void Test::print() {
        ::Utilities::for_all(m_vec_struct_privateimpl,&Test::Struct_PrivateImpl::m_privateimpl,&Test::CPrivateImpl::print);
    }    

// This is the main function
int main() {
    Test t;
    t.print();
}

Я получаю сообщение об ошибке с именем memvarимеет функцию Op.

Это пример кода. У меня есть много функций для вызова в классе PrivateImpl.

Пожалуйста, помогите мне, как решить эту проблему.

1 Ответ

2 голосов
/ 26 сентября 2019

Синтаксис для доступа через указатель члена: .* или ->*:

class Utilities {
public:
    template <typename Container, typename MemberVar, typename Operator>
    static void for_all(Container& C, MemberVar memvar, Operator Op)
    {
        for (auto& element : C) {
            ((*(element.*memvar)).*Op)();
        }
    }
};

Демо

...