[英]Member detection using void_t
對於C ++ 14中的成員檢測,我在這里使用了基於示例的代碼,但它似乎沒有用。
一個完整的例子:
#include <string>
template <typename...>
using void_t = void;
template <typename, typename = void> class HasMember_substr : public std::false_type {};
template <typename T> class HasMember_substr<T, void_t<typename T::substr>> : public std::true_type {};
template <typename, typename = void> class HasMember_fff : public std::false_type {};
template <typename T> class HasMember_fff<T, void_t<typename T::fff>> : public std::true_type {};
static_assert(HasMember_substr<std::string>::value, "");
static_assert(!HasMember_fff<std::string>::value, "");
int main() { return 0; }
在OS X上使用clang++ --std=c++14 test.cpp
編譯,編譯器版本( clang++ --version
): Apple LLVM version 7.0.2 (clang-700.1.81)
第二個斷言成功,但第一個失敗。 為什么? 我也嘗試使用decltype(T::substr)
而不是typename T::subset
,結果相同。
尋找T::substr
與查找名為substr
的成員函數不同。 gcc.godbolt.org的例子
您可以使用std::declval<T>()
並使用decltype來獲取成員函數的返回類型來檢查成員函數是否存在。
如果成員函數存在,則decltype(...)
將是格式良好的表達式,並且不會觸發SFINAE - 因此static_assert
將正常工作。
#include <string>
#include <type_traits>
#include <utility>
template <typename...>
using void_t = void;
template <typename, typename = void>
class HasMember_substr : public std::false_type {};
template <typename T>
class HasMember_substr<T, void_t<
decltype(std::declval<T>().substr(1, 1))>
> : public std::true_type {};
static_assert(HasMember_substr<std::string>::value, "");
int main() { return 0; }
請注意, decltype(std::declval<T>().substr(1, 1))
檢查T
是否具有可以使用參數1, 1
調用的substr
成員。 (例如,這不能保證是成員函數,也可以是函子數據成員。)
正如AndyG在評論中所說,另一種可能的方法是使用decltype
來“驗證”成員函數指針的類型。
例:
HasMember_substr<T, void_t< decltype(&T::substr)>
請注意,如果名稱substr
已重載,則此操作無效 ,並且無法保證在標准庫中使用任何類型 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.