Я бы хотел заменить SomeFunction
и SetArg
на что-то более общее из boost
.Похоже, что-то, что может быть сделано с bind
в сочетании с lambda
, но я не знаю, как.
Этот код очень прост, но я хотел бы заменить его, потому чтоМне нужен один для 2
и 3
и т.д. аргументов.
template<class T>
struct SomeFunction
{
T value;
SomeFunction(T s)
: value(s) {}
void operator()(T& s)
{
s = value;
}
};
template<class T>
SomeFunction<T> SetArg(T value)
{
return SomeFunction<T>(value);
}
Требования:
- Я хочу функцию, которая возвращает объект функции.
- Когда я вызываю этот объект функции, параметры передаются по ссылке.
- Функция изменяет объекты, переданные по ссылке, устанавливая для них предварительно заданные значения.
- В коде вышепредустановленные значения передаются по значению в
ctor
, но любой другой способ тоже подойдет.
Следующий код демонстрирует использование:
void main()
{
std::string t;
SetArg(std::string("hello"))(t);
assert(t == "hello");
}
Некоторый контекст:
Я хочу проверить клиентский код класса Foo
.Поэтому я хочу заменить реализацию func1
своей собственной, но гибким способом.
struct Foo
{
virtual void func1(std::string& s)
{
}
};
struct MockFoo : public Foo {
MOCK_METHOD1(func1, void(std::string&));
};
void ExampleTestCase::example()
{
MockFoo f;
std::string s;
EXPECT_CALL(f, func1(_))
.WillOnce(Invoke(SetArg(std::string("hello"))));
f.func1(s);
CPPUNIT_ASSERT_EQUAL(std::string("hello"), s);
}
Invoke принимает функцию или функциональный объект.Внутри новой реализации func1
он вызывает объект функции, возвращаемый SetArg
, и устанавливает в качестве аргумента строку "hello"
.
Invoke является частью gmock / gtest, а SetArg
- нет.