Skip to content

<xstd/misc/type_traits/is_specialization_of.hpp>

xstd::is_specialization_of, xstd::is_specialization_of_v

template<class T, template<class...> class Primary>
constexpr bool is_specialization_of_v = see below;

template<class T, template<class...> class Primary>
using is_specialization_of = bool_constant<is_specialization_of_v<T, Primary>>;

Whether a type is a specialization of a class template whose parameters are all types.

Value

true exactly when T is Primary<Args...> for some Args, and false otherwise.

Notes

  • A constrained primary template is no obstacle.
  • The question is exact: a const specialization is not one.
  • A primary template with a value parameter, such as array, cannot be named as Primary.
  • The concept and the trait agree.

Example

#include <xstd/misc/type_traits/is_specialization_of.hpp> // is_specialization_of_v
#include <iostream>                                       // boolalpha, cout
#include <optional>                                       // optional
#include <string>                                         // basic_string, string

// Prints a value, and what an optional holds rather than the optional itself.
template<class T>
auto print(T const& value) -> void
{
        if constexpr (xstd::is_specialization_of_v<T, std::optional>) {
                if (value.has_value()) {
                        print(*value);
                } else {
                        std::cout << "nothing";
                }
        } else {
                std::cout << value;
        }
}

auto main() -> int
{
        print(42);
        std::cout << ' ';
        print(std::optional<int>(7));
        std::cout << ' ';
        print(std::optional<int>());
        std::cout << ' ';
        print(std::optional<std::string>("text"));
        std::cout << '\n';

        // The question is exact: a const specialization is not one.
        std::cout << std::boolalpha;
        std::cout << "is_specialization_of_v<std::string, std::basic_string> is " << xstd::is_specialization_of_v<std::string, std::basic_string> << '\n';
        std::cout << "is_specialization_of_v<std::optional<int> const, std::optional> is " << xstd::is_specialization_of_v<std::optional<int> const, std::optional> << '\n';
}

Output:

42 7 nothing text
is_specialization_of_v<std::string, std::basic_string> is true
is_specialization_of_v<std::optional<int> const, std::optional> is false

See also

Entity Relation
specialization_of the concept, which also admits a const specialization