Check if std :: common_type exists

I want to write an auxiliary template that checks if the template parameter package has a common type, i.e. if applying std::common_type to a package determines the type.

Using std :: void_t with SFINAE, I came up with the following definition:

 template<typename... Types, typename Enable = void> struct has_common_type : std::false_type { }; template<typename... Types> struct has_common_type<Types..., std::void_t<std::common_type<Types...>::type>> : std::true_type { }; 

This, however, does not work, because the template parameter package must be the last parameter. The compiler causes the following error:

 error: template parameter pack must be the last template parameter template<typename... Types, typename Enable = void> 

How can one define such a pattern?

+5
source share
1 answer

Option number 1

 template <typename... Ts> using has_common_type = std::experimental::is_detected<std::common_type_t, Ts...>; 

Demo


Option number 2

 template <typename AlwaysVoid, typename... Ts> struct has_common_type_impl : std::false_type {}; template <typename... Ts> struct has_common_type_impl<std::void_t<std::common_type_t<Ts...>>, Ts...> : std::true_type {}; template <typename... Ts> using has_common_type = typename has_common_type_impl<void, Ts...>::type; 

Demo 2

+5
source

Source: https://habr.com/ru/post/1265350/


All Articles