Я знаю, что можно написать что-то вроде этого:
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