Talk:More C++ Idioms/Member Detector

Idiom is outdated
I've added the outdated tag to this page because the  based detection idiom does all of this and more, and does it better (hence its inclusion in the C++17 standard library). I think it's important that we update this page to reflect the new idiom since when I first found this page, it kept me from finding the far more powerful idiom for quite some time. For more information on the detection idiom in C++17, see WG21 standards document N4436 David.s.hollman (discuss • contribs) 18:13, 4 March 2016 (UTC)

The C++11 code does not work
Does anybody know why the type of the check classes is exposed by typedef ... type? Maybe this could be explained in the article. --141.30.83.52 (discuss) 13:34, 11 September 2014 (UTC)

Where I try to given code:


 * 1) include

\ template < class T >                                                             \ class HasMember_##member                                                         \ {                                                                                \ private:                                                                          \ using Yes = char[2];                                                         \ using No = char[1];                                                          \ \   struct Fallback { int member; };                                              \ struct Derived : T, Fallback { };                                            \ \   template < class U >                                                          \ static No& test ( decltype(U::member)* );                                    \ template < typename U >                                                      \ static Yes& test ( U* );                                                     \ \ public:                                                                          \ static constexpr bool RESULT = sizeof(test(nullptr)) == sizeof(Yes); \ };                                                                               \                                                                                  \ template < class T >                                                              \ struct has_member_##member                                                       \
 * 1) define GENERATE_HAS_MEMBER(member)                                              \
 * public std::integral_constant::RESULT>             \

{ };                                                                             \

struct one { int size const { return 1; }; };

struct two {};

GENERATE_HAS_MEMBER(size) // Creates 'has_member_att'.

int main { std::cerr << has_member_size ::value << '\n'; std::cerr << has_member_size ::value << '\n'; }

I get:

clang++-mp-3.5 -std=c++11 sss.cc && ./a.out sss.cc:37:1: error: call to 'test' is ambiguous GENERATE_HAS_MEMBER(size) // Creates 'has_member_att'. ^ sss.cc:21:43: note: expanded from macro 'GENERATE_HAS_MEMBER' static constexpr bool RESULT = sizeof(test(nullptr)) == sizeof(Yes); \ ^ sss.cc:37:1: note: in instantiation of template class 'HasMember_size ' requested here GENERATE_HAS_MEMBER(size) // Creates 'has_member_att'. ^ sss.cc:26:39: note: expanded from macro 'GENERATE_HAS_MEMBER'
 * public std::integral_constant::RESULT>             \

^ :245:1: note: expanded from here HasMember_size ^ sss.cc:42:16: note: in instantiation of template class 'has_member_size ' requested here std::cerr << has_member_size ::value << '\n'; ^ sss.cc:37:1: note: candidate function [with U = HasMember_size ::Derived] GENERATE_HAS_MEMBER(size) // Creates 'has_member_att'. ^ sss.cc:16:16: note: expanded from macro 'GENERATE_HAS_MEMBER' static No& test ( decltype(U::member)* );                                    \ ^ sss.cc:37:1: note: candidate function [with U = HasMember_size ::Derived] sss.cc:18:17: note: expanded from macro 'GENERATE_HAS_MEMBER' static Yes& test ( U* );                                                     \ ^