Để phát hiện thành viên trong C++ 14, tôi đã sử dụng mã dựa trên ví dụ here, nhưng dường như không hoạt động.Phát hiện thành viên bằng cách sử dụng void_t
Một ví dụ hoàn chỉnh:
#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; }
Biên soạn bằng clang++ --std=c++14 test.cpp
trên OS X, phiên bản trình biên dịch (clang++ --version
): Apple LLVM version 7.0.2 (clang-700.1.81)
Các khẳng định thứ hai thành công, nhưng là người đầu tiên thất bại. Tại sao? Tôi cũng đã thử sử dụng decltype(T::substr)
thay vì typename T::subset
, với cùng một kết quả.
'T :: substr' không giống với' T {}. Substr' –
Có phải 'substr' là một hàm bị quá tải trong quá trình triển khai của bạn không? (Nó được cho phép.) – aschepler
Bạn đã sao chép một ví dụ về thử nghiệm cho một loại, và mong đợi mã tương tự để làm việc để thử nghiệm cho một chức năng thành viên. Điều đó rõ ràng sẽ không hoạt động. 'std :: string :: substr' không phải là một kiểu, do đó,' typename T :: substr' rõ ràng là vô nghĩa. Bạn nên đã sao chép ví dụ rằng các bài kiểm tra cho pre-increment. –