Which cannot be implemented without compiler hooks?

I have written up a complete answer here — it’s a work in progress, so I’m giving the authoritative hyperlink even though I’m cutting-and-pasting the text into this answer. Also see libc++’s documentation on Type traits intrinsic design. is_union is_union queries an attribute of the class that isn’t exposed through any other means; in C++, … Read more

Is it possible to determine if a type is a scoped enumeration type?

I think testing if it is an enum and not implicitly convertible to the underlying type should do the trick. template <typename T, bool B = std::is_enum<T>::value> struct is_scoped_enum : std::false_type {}; template <typename T> struct is_scoped_enum<T, true> : std::integral_constant<bool, !std::is_convertible<T, typename std::underlying_type<T>::type>::value> {};

What do compilers do with compile-time branching?

TL;DR There are several ways to get different run-time behavior dependent on a template parameter. Performance is usually equal, so flexibility and maintainability are the main concern. In all cases, the various thin wrappers and constant conditional expressions will all be optimized away on any decent compiler for release builds. Below a small summary with … Read more

Check if a variable type is iterable?

You may create a trait for that: namespace detail { // To allow ADL with custom begin/end using std::begin; using std::end; template <typename T> auto is_iterable_impl(int) -> decltype ( begin(std::declval<T&>()) != end(std::declval<T&>()), // begin/end and operator != void(), // Handle evil operator , ++std::declval<decltype(begin(std::declval<T&>()))&>(), // operator ++ void(*begin(std::declval<T&>())), // operator* std::true_type{}); template <typename T> std::false_type … Read more

Checking a member exists, possibly in a base class, C++11 version

Actually, things got much easier in C++11 thanks to the decltype and late return bindings machinery. Now, it’s just simpler to use methods to test this: // Culled by SFINAE if reserve does not exist or is not accessible template <typename T> constexpr auto has_reserve_method(T& t) -> decltype(t.reserve(0), bool()) { return true; } // Used … Read more

check variadic templates parameters for uniqueness

Passing a pointer to base_all<U…> merely requires the existence of a declaration of base_all<U…>. Without attempting the to access the definition, the compiler won’t detect that the type is actually ill-defined. One approach to mitigate that problem would be to use an argument which requires a definition of base_all<U…>, e.g.: template< class …T> struct base_all … Read more

Check traits for all variadic template arguments

Define all_true as template <bool…> struct bool_pack; template <bool… v> using all_true = std::is_same<bool_pack<true, v…>, bool_pack<v…, true>>; And rewrite your constructor to // Check convertibility to B&; also, use the fact that getA() is non-const template<typename… Args, typename = std::enable_if_t<all_true<std::is_convertible<Args&, B&>{}…>> C(Args&… args) : member{args.getA()…} {} Alternatively, under C++17, template<typename… Args, typename = std::enable_if_t<(std::is_convertible_v<Args&, B&> … Read more

How to write `is_complete` template?

The answer given by Alexey Malistov can be used on MSVC with a minor modification: namespace { template<class T, int discriminator> struct is_complete { static T & getT(); static char (& pass(T))[2]; static char pass(…); static const bool value = sizeof(pass(getT()))==2; }; } #define IS_COMPLETE(X) is_complete<X,__COUNTER__>::value Unfortunately, the __COUNTER__ predefined macro is not part of … Read more

tech