Metaprogramming: Template Selection Based on Function Overload
In C metaprogramming, defining template functions conditionally based on type properties is a common technique. However, in some cases, it can be challenging to define the opposite scenario, where a template is selected based on the absence of a particular function.
Specifically, in the example provided, the goal is to define a template function stringify that selects between two implementations:
The problem arises when trying to express the latter condition. The following unsuccessful attempt attempts to use nested enable_if templates to check if to_string is not defined:
template<typename T> enable_if_t<!decltype(to_string(T{})::value, string> (T t){ return static_cast<ostringstream&>(ostringstream() << t).str(); }
To solve this issue, we can utilize Walter Brown's void_t type trait:
template <typename...> using void_t = void;<p>Using this, we can define the has_to_string trait as follows:</p> <pre class="brush:php;toolbar:false">template<typename T, typename = void> struct has_to_string : std::false_type { }; template<typename T> struct has_to_string<T, void_t<decltype(std::to_string(std::declval<T>()))> > : std::true_type { };
Now, the stringify template can be defined using conditional template specialization based on the has_to_string trait:
template<typename T> enable_if_t<has_to_string<T>::value, string> stringify(T t){ return std::to_string(t); } template<typename T> enable_if_t<!has_to_string<T>::value, string> stringify(T t){ return static_cast<ostringstream&>(ostringstream() << t).str(); }
This solution effectively selects the appropriate implementation of stringify based on whether std::to_string is defined for the given type.
The above is the detailed content of How Can We Implement Template Selection Based on the Absence of a Function in C Metaprogramming?. For more information, please follow other related articles on the PHP Chinese website!