My goal is to implement a predicate that detects the presence of a nested using
alias (or typedef
) that acts as a light-weight tag to indicate that a class has some attribute (for the purposes of generic programming). For example, a has_my_tag<T>
predicate should behave as follows:
struct A {
using my_tag = void;
};
struct B {};
int main()
{
static_assert(has_my_tag<A>::value, ""); // evaluate to true if my_tag=void is present
static_assert(!has_my_tag<B>::value, ""); // false otherwise
}
User @JoelFalcou called this the "lightweight type categorization idiom" and provided a solution in this answer. I have been unable to find any references for an idiom of that name (do you know of any?) Here's Joel's implementation of has_my_tag<>
:
template<class T, class R = void>
struct enable_if_type { typedef R type; };
template<class T, class Enable = void>
struct has_my_tag : std::false_type {};
template<class T>
struct has_my_tag<T, typename enable_if_type<typename T::my_tag>::type> :
std::true_type
{};
And here is a working version on the Compiler Explorer: https://godbolt.org/z/EEOBb-
I have come up with the following simplified version:
template<class T, class Enable = void>
struct has_my_tag : std::false_type {};
template<class T>
struct has_my_tag<T, typename T::my_tag> : std::true_type
{};
My Questions: Is the simplified version an acceptable way to implement the idiom? Are there circumstances where it would fail? Is there a simpler version that works in C++11? Which version should I prefer?
From what I understand, Joel's version would allow my_tag
to alias any type, whereas my version requires my_tag
to alias void
. But given the goal of tagging types for light-weight predicate testing, I am not clear which version is to be preferred.
Auxiliary questions: Also, are there other names for this idiom? Is it used in any libraries that I could investigate? So far I have not found a name that brings up any search results.