как избежать повторения объявления функции в оболочке - PullRequest
0 голосов
/ 07 декабря 2018

Я знаю, что можно написать что-то вроде этого:

struct Impl {
    static bool f(int);
};

template<class Impl> struct Helper {
    static constexpr auto f = Impl::f;
};

Но есть ли способ избежать вставки копий параметров функции и возвращаемых значений в таком случае:

struct Impl {
    static bool f(int);
};

struct Helper {
    static const auto f = bind(*Impl::f, not_really_pimpl);

    static Impl *not_really_pimpl;
};

Я не ожидаю, что это сработает (и это не так), но есть ли разумный способ избежать повторения параметров f () и возвращаемого значения в такой оболочке?

РЕДАКТИРОВАТЬ: Сотни глупых тестов делают Helper :: f ().Теперь кто-то хотел издеваться над помощником.Helper - это просто пространство имен статических функций, которые случайно оказались классом.Да, я знаю, что статические функции не допускают насмешки и блаблабла, но они просто хотят этого.

Я не хочу менять много кода для просто насмешки.Также некоторое количество тестов, которые необходимо переписать, если выбрать между Helper: Impl и Helper: MockImpl, должно быть выполнено во время компиляции для всех из них, потому что они используют оригинальный Helper :: f ().

Также изменение всех мест, где Helper :: f () вызывается для другого синтаксиса, не является хорошей идеей.Поэтому я просто слежу за хаком: модульное тестирование Google Mock со статическими методами c ++ с той единственной разницей, что я не могу переключить Helper с параметром шаблона для всего во время компиляции.Проще просто добавить статический указатель к реализации и вызвать его из статических функций.Тогда это mockable / unmockable во время выполнения.Он просто добавляет еще больше копий, чем копирует сам.

Я думал, что существует разумный (не слишком много кода, чтобы иметь смысл сравнивать с повторением), чтобы как-то основывать эти параметры на шаблонах, но, поскольку я переключаю указатель во время выполнения, я думаю, что это невозможно?Поэтому мне нужно написать

struct Helper {
    static bool f(int) { not_really_pimpl->f(); }
    static NotReallyPimpl real_impl;
    static Impl* not_really_pimpl = &real_pimpl; // pseudocode
};

, а также

struct NotReallyPimpl {
   virtual bool f(int) { /* here is the job done */ }
};

, а также

struct MockNotReallyPimpl : public NotReallyPimpl {
    MOCK_METHOD1(f, bool(int));
};

Тогда старый тестовый код будет использовать Helper :: f ().Какой-то новый тестовый код, который хочет издеваться над Хелпером:

MockNotReallyPimpl mock;
Helper::not_really_pimpl = &mock;
EXPECT_CALL(mock, f, blablabla).WillBlabla(WithBlablabla())).
Helper::not_really_pimpl = Helper::real_impl; // in TearDown
...