我想对类模板的等效模板化成员函数进行单元测试。 (作为背景,我想为库的“经典”功能符号的用户提供.bar()以及默认的符号|,&等,但我不想重复完整的测试代码。)>
#include <utility>
template <typename T>
struct foo
{
template <typename U>
auto bar(U&& u)&& {
// whatever happens here.
return foo<T>();
}
template <typename U>
auto operator|(U&& u)&& {
return bar(std::forward<U>(u));
}
template <typename U>
auto bar(U&& u) const& {
// whatever happens here.
return foo<T>();
}
template <typename U>
auto operator|(U&& u) const& {
return bar(std::forward<U>(u));
}
};
int main() {
using void_t = void();
using op_t = foo<void>(foo<void>::*)(void_t)&&;
op_t ops[] = {static_cast<op_t>(&foo<void>::bar<void_t>),
static_cast<op_t>(&foo<void>::operator|<void_t>)};
for (const auto& op : ops) {
auto sut = (foo<void>{}.*op)([](){});
// test the behaviour of sut
}
}
clang例如,报告我“重载函数'bar'的地址不能被static_cast键入'op_t'”
还是我走错了路,这是不可能的? (我尝试了clang 6和gcc 7)
答案 0 :(得分:1)
我可以通过将op_t
更改为
using op_t = foo<void>(foo<void>::*)(void_t &&) &&;
// ^^
和sut
至
auto sut = (foo<void>{}.*op)(*[](){});
// ^
({[](){}
可以转换为函数指针,但是*op
引用了一个函数,因此我们必须取消对该指针的引用)。
或者,您也可以将sut
更改为
void_t
using void_t = void (*)();
// ^^^
现在void_t
已经是一个函数指针,因此您不必取消引用。