3 回答
TA贡献1895条经验 获得超3个赞
joshperry的回答非常聪明和优雅,但是(如后文所述)它不能正确检查foo()的签名,并且不能与基本类型(如int)一起使用:这会导致编译器错误。我将提出一种可以正确处理继承的成员并检查成员函数签名的技术。我将不做详细介绍,而是给您两个示例,并希望代码能说明一切。
范例1:
我们正在检查具有以下签名的成员: T::const_iterator begin() const
template<class T> struct has_const_begin
{
typedef char (&Yes)[1];
typedef char (&No)[2];
template<class U>
static Yes test(U const * data,
typename std::enable_if<std::is_same<
typename U::const_iterator,
decltype(data->begin())
>::value>::type * = 0);
static No test(...);
static const bool value = sizeof(Yes) == sizeof(has_const_begin::test((typename std::remove_reference<T>::type*)0));
};
请注意,它甚至检查方法的一致性,并且也适用于原始类型。(我的意思has_const_begin<int>::value是假的,不会引起编译时错误。)
例子2
现在我们正在寻找签名: void foo(MyClass&, unsigned)
template<class T> struct has_foo
{
typedef char (&Yes)[1];
typedef char (&No)[2];
template<class U>
static Yes test(U * data, MyClass* arg1 = 0,
typename std::enable_if<std::is_void<
decltype(data->foo(*arg1, 1u))
>::value>::type * = 0);
static No test(...);
static const bool value = sizeof(Yes) == sizeof(has_foo::test((typename std::remove_reference<T>::type*)0));
};
请注意,MyClass不一定是默认可构造的,也不必满足任何特殊概念。该技术也适用于模板成员。
我热切地等待对此的意见。
- 3 回答
- 0 关注
- 522 浏览
添加回答
举报