patterncppMinor
A trait class to detect whether a template is specialized for a given type
Viewed 0 times
templatewhetherspecializedtypetraitforclassgivendetect
Problem
Today's question will just be about a small utility that I needed at some point for one of my projects: a template to detect whether a template is specialized for a given type. The utility uses
Here is the template utility I wrote to detect whether a template has a specialization for a given type, for SFINAE purpose:
And here is a small example of how it can be used:
Is there any way I could improve this specialization trait? Any kind of review is welcome :)
std::void_t from C++17, but this alias template is simle enough to be implemented in you favourite C++ revision, whichever it is:template
struct voider
{
using type = void;
};
template
using void_t = typename voider::type;Here is the template utility I wrote to detect whether a template has a specialization for a given type, for SFINAE purpose:
template class,
typename,
typename=void
>
struct is_specialized:
std::false_type
{};
template class Template,
typename T
>
struct is_specialized{})>>:
std::true_type
{};And here is a small example of how it can be used:
template
struct foo;
template<>
struct foo {};
template<>
struct foo {};
int main()
{
// Should print 1 1 0
std::cout ::value ::value ::value;
}Is there any way I could improve this specialization trait? Any kind of review is welcome :)
Solution
I think there's an issue with wording here. What you're testing is if a given instantiation of a class template is default constructible. You're not testing if it's "specialized". You cannot check for that. How would you differentiate between:
Back to your example - just because you cannot construct an object of a particular instantiation (e.g.
Which you would use as
But really, since we're just testing for constructibility, we should just use what's in the standard:
template struct foo { };
template <> struct foo { };
// is foo the primary or the specialization?Back to your example - just because you cannot construct an object of a particular instantiation (e.g.
foo) doesn't mean that you can't name the type. You can do that just fine. That lets you simplify your trait down to:template
struct is_specialized : std::false_type
{};
template
struct is_specialized>
: std::true_type
{};Which you would use as
is_specialized::value (true) or is_specialized>::value (false). But really, since we're just testing for constructibility, we should just use what's in the standard:
template
using is_specialized = std::is_default_constructible;Code Snippets
template <typename T> struct foo { };
template <> struct foo<int> { };
// is foo<X> the primary or the specialization?template <typename, typename=void>
struct is_specialized : std::false_type
{};
template<typename T>
struct is_specialized<T, void_t<decltype(T{})>>
: std::true_type
{};template <typename T>
using is_specialized = std::is_default_constructible<T>;Context
StackExchange Code Review Q#98214, answer score: 6
Revisions (0)
No revisions yet.