0

我想SomeFunction用. 看起来可以与结合使用,但我不知道如何。SetArgboostbindlambda

这段代码非常简单,但我想替换它的原因是我需要一个 for23etc 参数。

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");
}

一些上下文:

我想测试 class 的客户端代码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不是。

4

1 回答 1

1

这是我想出的。setter 可能需要一些调整,operator()因为我们并没有真正从这里可能的移动语义中受益,但我现在无法弄清楚。

另请注意,这会大量使用您可能无法使用的 C++11 功能。

#include <string>
#include <iostream>
#include <tuple>

// set arbitrary values to 
template<typename... Args>
struct setter {
  // needed because we cannot use initializer lists as they require assignment
  setter(const std::tuple<Args&...>& t) : t(t) {}
  std::tuple<Args...> t;

  // again a template to trigger deduction again
  template<typename... Args2>
  void operator()(Args2&&... args) {
    t = std::make_tuple(args...);
  }
};

template<typename... Args>
setter<Args&...> create_setter(Args&... args) {
  return setter<Args&...>(std::tie(args...));
}

int main()
{
  int i = 0;
  long l = 1;
  std::string foo = "foo";

  auto s = create_setter(i, l, foo);

  s(23, 42, "bar");
  std::cout << i << std::endl;
  std::cout << l << std::endl;
  std::cout << foo << std::endl;

  return 0;
}
于 2011-10-19T01:12:21.907 回答