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 關注
- 547 瀏覽
添加回答
舉報