gpt4 book ai didi

c++ - 如何转发未命名的函数参数

转载 作者:行者123 更新时间:2023-12-03 07:03:39 25 4
gpt4 key购买 nike

因此,我正在尝试为我的虚拟类函数创建一个模拟宏。
这是带有一个模拟函数的模拟类的示例。 (这按预期工作)

class MockEnvironment : public IEnvironment {
public:
using runType = int(std::string program,
std::vector<std::string> arguments);

MockedFunction<runType> runMock = MockedFunction<runType>("run");

int run(std::string program, std::vector<std::string> arguments) override {
return runMock(program, arguments);
}

// MOCK_METHOD(int, run, (std::string, std::vector<std::string>)); // this is the goal
};

MockedFunction是带有operator()的类,应在调用函数时调用该类。
我的目标是将函数包装在宏中,以便能够模拟任何函数。您可能会看到的问题是,在泛化时,我将需要处理带有未命名参数的函数。

#define MOCK_METHOD(ret, name, args) \
MockedFunction<ret(args)> mocked_##name = \
MockedFunction<ret(args)>(#name); \
ret name##Mock(args) { /* how to solve? */ }

// This would expand to something like
MockedFunction<...> runMock = MockedFunction<...>("run"); // More detailed in above example

int run(std::string, std::vector<std::string>) override {
return runMock(/*how to forward the arguments when they do not have names?*/)
}
我曾考虑过使用某种可变文本模板,但是还没有找到任何使它工作的方法。我也曾尝试阅读谷歌的模拟实现,但我很难看到他们如何解决它。
所以我的问题很简单。如何将 run中参数的内容移动到要调用的函数?
我最多可以使用c++ 17。我确实意识到,如果在宏中指定需要多少个参数,会更容易,但是,如果可以解决更一般的示例,那将是最佳选择。
编辑:
如果我事先知道参数的数量,这是我想出的最好的方法。
#define INTERNAL_MOCK_METHOD_COMMON(ret, name, args)                           \
using name##T = ret(args); \
unittest::MockedFunction<ret(args)> mock_##name = \
unittest::MockedFunction<ret(args)>(#name);

#define MOCK_METHOD(ret, name) \
INTERNAL_MOCK_METHOD_COMMON(ret, name, ()) \
ret name() { \
return mock_##name(); \
}

#define MOCK_METHOD1(ret, name, args) \
INTERNAL_MOCK_METHOD_COMMON(ret, name, args) \
ret name(typename unittest::MockedFunction<name##T>::ArgT<0>::type a) { \
return mock_##name(a); \
}

#define MOCK_METHOD2(ret, name, args) \
INTERNAL_MOCK_METHOD_COMMON(ret, name, args) \
ret name(typename unittest::MockedFunction<name##T>::ArgT<0>::type a, \
typename unittest::MockedFunction<name##T>::ArgT<1>::type b) { \
return mock_##name(a, b); \
}

// ...

template <typename T>
class MockedFunction {};

template <typename ReturnT, typename... ArgsT>
class MockedFunction<ReturnT(ArgsT...)> {
public:
// Return argument type at the specified index
template <int i>
struct ArgT {
using type = typename std::tuple_element_t<i, std::tuple<ArgsT...>>;
};
然后可以像这样使用

class IObject {
public:
virtual int update() = 0;
virtual void setValue(int) = 0;
};

class MockObject : public IObject {
public:
MOCK_METHOD(int, update);
MOCK_METHOD1(void, setValue, (int));
};
需要说明的是:不必用数字指定参数的数量会很好。

最佳答案

您不能使用未命名的参数。您可以考虑命名它们,也许像这样:

#define MOCK_METHOD(ret, name, args, names)                                           \
MockedFunction<ret(args)> mocked_##name = \
MockedFunction<ret(args)>(#name); \
ret name##Mock(args) { return runMock names; }

MOCK_METHOD(int, run, (std::string s, std::vector<std::string> v), (s, v));

关于c++ - 如何转发未命名的函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64087151/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com