【发布时间】:2017-03-15 12:38:02
【问题描述】:
我正在尝试编写一个模板元函数来检测一个类型是否具有 void 类型的成员函数。
目前我可以使用 SFINAE 来检测成员函数是否具有明确的类型,例如 double、int 等。使用类似
template<typename C> static auto Test(void*) -> decltype(int{std::declval<C>().foo()}, Yes{});
当然,我可以将其反转(如附加代码 sn-p 所示)以测试它不是 int,但我无法弄清楚如何测试它是否为 void。
下面的代码sn-p当前输出
A does not have void foo
B has void foo
C has void foo
但是,C 的 foo() 方法具有 double 类型,因此这是不正确的输出。如何调整它以正确检查 void foo()?
#include <iostream>
#include <memory>
class A {
public:
int foo() {
return 0;
}
};
class B {
public:
void foo() {
}
};
class C {
public:
double foo() {
return 0;
}
};
template <typename T>
class has_void_foo {
private:
typedef char Yes;
typedef Yes No[2];
template<typename C> static auto Test(void*) -> decltype(int{std::declval<C>().foo()}, Yes{});
template<typename> static No& Test(...);
public:
static bool const value = sizeof(Test<T>(0)) != sizeof(Yes);
};
int main(void) {
std::cout << "A ";
if (has_void_foo<A>::value) {
std::cout << " has void foo";
} else {
std::cout << " does not have void foo";
}
std::cout << std::endl << "B ";
if (has_void_foo<B>::value) {
std::cout << " has void foo";
} else {
std::cout << " does not have void foo";
}
std::cout << std::endl << "C ";
if (has_void_foo<C>::value) {
std::cout << " has void foo";
} else {
std::cout << " does not have void foo";
}
std::cout << std::endl;
return 0;
}
【问题讨论】:
-
你知道 C++11 中
<type_traits>中的std::is_void吗?
标签: c++ template-meta-programming