使用 google mock 测试 C++ 时无法推断模板参数
Could not deduce template argument when testing C++ with google mock
我的代码使用 Google mock 来测试 class EventLogger.
首先编译失败是因为编译器在宏中没有找到模板的参数,导致参数扣除失败:
candidate: template<class T, class ... Args> auto Filler<traceType>::fill(Args&& ...)
[with T = T; Args = {Args ...}; Class1 traceType = (Class1)1u]
WRAP_MOCKED_TEMPL_METHOD_1(fill, T);
^
In definition of macro 'WRAP_MOCKED_TEMPL_METHOD_1'
auto NAME(Args &&...args)\
^
Template argument deduction/substitution failed:
WRAP_MOCKED_TEMPL_METHOD_1(fill, T);
Couldn't deduce template parameter 'T''
所以我试图在调用函数时显式添加参数(在代码中注释//V2)但随后出现另一个错误消息:
filler.fill<Message>(buffer, data, getMessage());
In member function
void EventLogger<traceType>::write(const buffer&, const Message&):
Error: expected primary-expression before '>' token
`filler.fill<Message>(buffer, data, streamInd);`
^
###代码###
这是我的代码。
Class 测试
template <Class1 traceType>
class EventLogger
{
public:
template <typename Message>
void write(const c1& buffer, const Message& data)
{
filler.fill(buffer, data, getMessage()); // V1
filler.fill<Message>(buffer, data, getMessage()); // V2
}
private:
Filler<traceType> filler;
};
模拟Class
template <Class1 traceType>
class MockFiller
{
public:
MOCK_METHOD3(send, void(c1, const Data::SendReq& msg, Class1::StreamInd&));
MOCK_METHOD3(receive, void(c1, const Data::ReceiveReq& msg, Class1::StreamInd&));
template <typename Message>
void fill(c1 buffer, const Message&, Class1::StreamInd& streamInd)
{
ASSERT_TRUE(false);
}
};
您可以在Google documentation中找到宏MOCK_METHODX
的解释。
Mock 专业化Class
template <>
template <>
void MockFiller<Class1::TYPE_1>::fill<Data::SendReq>(c1 buffer,
const Data::SendReq& msg, Class1::StreamInd& streamInd)
{
send(buffer, msg, streamInd);
}
template <>
template <>
void MockFiller<Class1::TYPE_1>::fill<Data::ReceiveReq>(c1 buffer,
const Data::ReceiveReq& msg, Class1::StreamInd& streamInd)
{
receive(buffer, msg, streamInd);
}
MockFiller 的构造函数
class MockFillerConstructor
{
public:
MOCK_METHOD0(construct, std::shared_ptr<MockFiller<Class1::TYPE_1>>());
};
Class 在 class 中调用,用它的宏
测试
#define WRAP_MOCKED_TEMPL_METHOD_1(NAME, TEMPL) \
template <typename TEMPL, typename ...Args>\
auto NAME(Args &&...args)\
{\
return this->mock().NAME<TEMPL>(std::forward<Args>(args)...);\
}
template <Class1 traceType>
class Filler : public CopyableMockBase<MockFiller<traceType>>
{
public:
WRAP_MOCKED_TEMPL_METHOD_1(fill, T);
};
所以我的问题是:
- 为什么编译器没有自动找到模板参数
- 为什么我的代码的 V2 包含语法错误
感谢您的帮助
我对 Google Mock 一无所知,但你的 V2 缺少 template
关键字:
filler.template fill<Message>(buffer, data, getMessage()); // V2
编译器解析EventLogger
时,不知道Filler<traceType>::fill
是什么,也不知道后面的<
是不是要打开一个模板列表参数 or 只是一个小于运算符。没有 template
关键字,它假定后者。
编辑哦等一下。对于V1,当然不能推导出T
。替换宏,您可以这样定义 Filler<traceType>::fill
:
template <typename T, typename... Args>
auto fill(Args &&...args)
{
return this->mock().fill<T>(std::forward<Args>(args)...);
}
(另请注意 this->mock().fill<T>
中缺失的 template
,但这不是重点)。 T
未在函数参数列表中引用。编译器将如何推断出它应该是什么?为什么你甚至需要 T
?你不能只做以下事情吗?
template <typename... Args>
auto fill(Args &&...args)
{
return this->mock().fill(std::forward<Args>(args)...);
}
我的代码使用 Google mock 来测试 class EventLogger.
首先编译失败是因为编译器在宏中没有找到模板的参数,导致参数扣除失败:
candidate: template<class T, class ... Args> auto Filler<traceType>::fill(Args&& ...)
[with T = T; Args = {Args ...}; Class1 traceType = (Class1)1u]
WRAP_MOCKED_TEMPL_METHOD_1(fill, T);
^
In definition of macro 'WRAP_MOCKED_TEMPL_METHOD_1'
auto NAME(Args &&...args)\
^
Template argument deduction/substitution failed:
WRAP_MOCKED_TEMPL_METHOD_1(fill, T);
Couldn't deduce template parameter 'T''
所以我试图在调用函数时显式添加参数(在代码中注释//V2)但随后出现另一个错误消息:
filler.fill<Message>(buffer, data, getMessage());
In member function
void EventLogger<traceType>::write(const buffer&, const Message&):
Error: expected primary-expression before '>' token
`filler.fill<Message>(buffer, data, streamInd);`
^
###代码### 这是我的代码。
Class 测试
template <Class1 traceType>
class EventLogger
{
public:
template <typename Message>
void write(const c1& buffer, const Message& data)
{
filler.fill(buffer, data, getMessage()); // V1
filler.fill<Message>(buffer, data, getMessage()); // V2
}
private:
Filler<traceType> filler;
};
模拟Class
template <Class1 traceType>
class MockFiller
{
public:
MOCK_METHOD3(send, void(c1, const Data::SendReq& msg, Class1::StreamInd&));
MOCK_METHOD3(receive, void(c1, const Data::ReceiveReq& msg, Class1::StreamInd&));
template <typename Message>
void fill(c1 buffer, const Message&, Class1::StreamInd& streamInd)
{
ASSERT_TRUE(false);
}
};
您可以在Google documentation中找到宏MOCK_METHODX
的解释。
Mock 专业化Class
template <>
template <>
void MockFiller<Class1::TYPE_1>::fill<Data::SendReq>(c1 buffer,
const Data::SendReq& msg, Class1::StreamInd& streamInd)
{
send(buffer, msg, streamInd);
}
template <>
template <>
void MockFiller<Class1::TYPE_1>::fill<Data::ReceiveReq>(c1 buffer,
const Data::ReceiveReq& msg, Class1::StreamInd& streamInd)
{
receive(buffer, msg, streamInd);
}
MockFiller 的构造函数
class MockFillerConstructor
{
public:
MOCK_METHOD0(construct, std::shared_ptr<MockFiller<Class1::TYPE_1>>());
};
Class 在 class 中调用,用它的宏
测试#define WRAP_MOCKED_TEMPL_METHOD_1(NAME, TEMPL) \
template <typename TEMPL, typename ...Args>\
auto NAME(Args &&...args)\
{\
return this->mock().NAME<TEMPL>(std::forward<Args>(args)...);\
}
template <Class1 traceType>
class Filler : public CopyableMockBase<MockFiller<traceType>>
{
public:
WRAP_MOCKED_TEMPL_METHOD_1(fill, T);
};
所以我的问题是:
- 为什么编译器没有自动找到模板参数
- 为什么我的代码的 V2 包含语法错误
感谢您的帮助
我对 Google Mock 一无所知,但你的 V2 缺少 template
关键字:
filler.template fill<Message>(buffer, data, getMessage()); // V2
编译器解析EventLogger
时,不知道Filler<traceType>::fill
是什么,也不知道后面的<
是不是要打开一个模板列表参数 or 只是一个小于运算符。没有 template
关键字,它假定后者。
编辑哦等一下。对于V1,当然不能推导出T
。替换宏,您可以这样定义 Filler<traceType>::fill
:
template <typename T, typename... Args>
auto fill(Args &&...args)
{
return this->mock().fill<T>(std::forward<Args>(args)...);
}
(另请注意 this->mock().fill<T>
中缺失的 template
,但这不是重点)。 T
未在函数参数列表中引用。编译器将如何推断出它应该是什么?为什么你甚至需要 T
?你不能只做以下事情吗?
template <typename... Args>
auto fill(Args &&...args)
{
return this->mock().fill(std::forward<Args>(args)...);
}