This is kind of a followup question to
Why can't I use traits with forwarding references in C++?
which has been correctly answered. However I tried my own solution below
#include <type_traits>
template <typename T, typename enable = void> struct Traits {
static const bool value = false;
};
template <typename T> struct Traits<T,std::enable_if<std::is_reference<T>::value>> {
static const bool value = Traits<typename std::remove_reference<T>::type>::value;
};
struct Zip{};
template <> struct Traits<Zip,void> {
static const bool value = true;
};
template <typename E>
void Execute(E && e){
static_assert(Traits<E>::value);
}
int main(){
auto z = Zip();
Execute(z);
}
the theory being that if the correct specialisation fails then the next most specialized will be the one that matches based on if T
is a reference. If this matches then the reference is stripped and we recurse hopefully getting a match. But this does not seem to work. Is there a way to fix this that keep the spirit of my attempt?
You are misusing std::enable_if
. As written, your Traits
struct is specialized on std::enable_if
itself, not its result. You need to access the nested ::type
type alias:
typename std::enable_if<std::is_reference<T>::value>::type
// or
std::enable_if_t<std::is_reference<T>::value>