非类型模板参数的特化
Specialization of non-type template argument
我有一个结构
template <auto& t>
struct Foo {
using Type = decltype(t);
};
我也有模板class:
template <typename T> class MyClass {};
我想为 MyClass 类型的任何参数创建此结构的特化:
template <typename T>
struct Foo <MyClass<T>& t> {
using Type = int;
};
我希望能够像这样使用这个 class:
Foo<true>::Type t = false;
此代码无法编译。我怎样才能做这种专业化?是否有其他方法可以使用 std::enable_if
来完成此操作?
您的代码接近所需的解决方案。专业化只需要一点不同的语法:
template <typename T> class MyClass {};
template < auto value >
struct Foo
{
void Check() { std::cout << "Default" << std::endl; }
};
template <typename T, MyClass<T> value>
struct Foo<value>
{
void Check() { std::cout << "Spezial" << std::endl; }
};
int main()
{
Foo<10> fi;
Foo<MyClass<int>{}> fm;
fi.Check();
fm.Check();
}
对于 gcc,它需要主干版本。 gcc 11 编译但提供错误结果!
根据 C++20 和 P0732R2(Class 在 Non-Type 模板参数中键入 )non-type 模板参数可能是 class 类型,允许您使用部分特化来特化比主模板的“任何 non-type 模板”参数更特化的 non-type 模板参数。
#include <type_traits>
// some class types
template<typename T> struct S{};
struct U {};
template<auto> // _any_ non-type template parameter
struct is_using_primary_template : std::true_type {};
// partial specialization for specialization of a class template type.
template<typename T, S<T> s>
struct is_using_primary_template<s> : std::false_type {};
// explicit specialization for some class type values.
constexpr S<void> sv{};
constexpr U u{};
template<>
struct is_using_primary_template<sv> : std::false_type {};
template<>
struct is_using_primary_template<u> : std::false_type {};
template<auto v>
constexpr bool is_using_primary_template_v{is_using_primary_template<v>::value};
static_assert(is_using_primary_template_v<0>);
static_assert(!is_using_primary_template_v<S<int>{}>); // partial spec.
static_assert(!is_using_primary_template_v<S<char>{}>); // partial spec.
static_assert(!is_using_primary_template_v<S<void>{}>); // explicit spec.
static_assert(!is_using_primary_template_v<sv>); // explicit spec.
static_assert(!is_using_primary_template_v<u>); // explicit spec.
请注意,这不是偏特化的任何特殊情况,而只是满足每个偏特化的所有模板参数都可推导的最低要求的典型用例。
GCC 11 拒绝此代码是一个错误(Bug 99699), which seems to have been (silently or via another bug report?) fixed in GCC 12/trunk. See the Q&A 了解详情。
有关如何将此应用于您的特定示例,请参阅
我有一个结构
template <auto& t>
struct Foo {
using Type = decltype(t);
};
我也有模板class:
template <typename T> class MyClass {};
我想为 MyClass 类型的任何参数创建此结构的特化:
template <typename T>
struct Foo <MyClass<T>& t> {
using Type = int;
};
我希望能够像这样使用这个 class:
Foo<true>::Type t = false;
此代码无法编译。我怎样才能做这种专业化?是否有其他方法可以使用 std::enable_if
来完成此操作?
您的代码接近所需的解决方案。专业化只需要一点不同的语法:
template <typename T> class MyClass {};
template < auto value >
struct Foo
{
void Check() { std::cout << "Default" << std::endl; }
};
template <typename T, MyClass<T> value>
struct Foo<value>
{
void Check() { std::cout << "Spezial" << std::endl; }
};
int main()
{
Foo<10> fi;
Foo<MyClass<int>{}> fm;
fi.Check();
fm.Check();
}
对于 gcc,它需要主干版本。 gcc 11 编译但提供错误结果!
根据 C++20 和 P0732R2(Class 在 Non-Type 模板参数中键入 )non-type 模板参数可能是 class 类型,允许您使用部分特化来特化比主模板的“任何 non-type 模板”参数更特化的 non-type 模板参数。
#include <type_traits>
// some class types
template<typename T> struct S{};
struct U {};
template<auto> // _any_ non-type template parameter
struct is_using_primary_template : std::true_type {};
// partial specialization for specialization of a class template type.
template<typename T, S<T> s>
struct is_using_primary_template<s> : std::false_type {};
// explicit specialization for some class type values.
constexpr S<void> sv{};
constexpr U u{};
template<>
struct is_using_primary_template<sv> : std::false_type {};
template<>
struct is_using_primary_template<u> : std::false_type {};
template<auto v>
constexpr bool is_using_primary_template_v{is_using_primary_template<v>::value};
static_assert(is_using_primary_template_v<0>);
static_assert(!is_using_primary_template_v<S<int>{}>); // partial spec.
static_assert(!is_using_primary_template_v<S<char>{}>); // partial spec.
static_assert(!is_using_primary_template_v<S<void>{}>); // explicit spec.
static_assert(!is_using_primary_template_v<sv>); // explicit spec.
static_assert(!is_using_primary_template_v<u>); // explicit spec.
请注意,这不是偏特化的任何特殊情况,而只是满足每个偏特化的所有模板参数都可推导的最低要求的典型用例。
GCC 11 拒绝此代码是一个错误(Bug 99699), which seems to have been (silently or via another bug report?) fixed in GCC 12/trunk. See the Q&A
有关如何将此应用于您的特定示例,请参阅