我知道可以这样写:
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 unit testing static methods c++,唯一的区别是我无法在编译时使用模板参数切换Helper。仅添加指向实现的静态指针并从静态函数中调用它会更简单。然后在运行时是可模拟的/不可模拟的。它比模拟本身增加了更多的复制粘贴功能。
我当时以为存在某种合理的(相对于重复而言,没有太多代码使之有意义)以某种方式将这些参数基于模板,但是当我在运行时切换指针时,我认为这不可能吗?所以我不得不写
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()。希望模拟Helper的一些新测试代码可以做到:
MockNotReallyPimpl mock;
Helper::not_really_pimpl = &mock;
EXPECT_CALL(mock, f, blablabla).WillBlabla(WithBlablabla())).
Helper::not_really_pimpl = Helper::real_impl; // in TearDown