在没有结构样板代码的情况下约束模板参数的简短方法
Short way to constrain template parameter without boiler plate code for a struct
考虑这个例子:
#include <iostream>
template <typename T, std::size_t I>
struct Foo
{
};
template <typename T>
struct specializes_foo : std::false_type {};
template <typename T, std::size_t I>
struct specializes_foo<Foo<T, I>> : std::true_type {};
template <typename T>
concept foo = specializes_foo<T>::value;
int main()
{
std::cout << foo<int> << "\n";
std::cout << foo<Foo<int,3>> << "\n";
}
C++20 有更短的方法吗?我知道你可以为“专门化模板”做一个概念,例如:
// checks if a type T specializes a given template class template_class
// note: This only works with typename template parameters.
// e.g.: specializes<std::array<int, 3>, std::array> will yield a compilation error.
// workaround: add a specialization for std::array.
namespace specializes_impl
{
template <typename T, template <typename...> typename>
struct is_specialization_of : std::false_type {};
template <typename... Args, template <typename...> typename template_class>
struct is_specialization_of<template_class<Args...>, template_class> : std::true_type {};
}
template <typename T, template <typename...> typename template_class>
inline constexpr bool is_specialization_of_v = specializes_impl::is_specialization_of<T,template_class>::value;
template <typename T, template <typename...> typename template_class>
using is_specialization_of_t = specializes_impl::is_specialization_of<T,template_class>::type;
template<typename T, template <typename...> typename template_class>
concept specializes = is_specialization_of_v<T, template_class>;
但是,使用非类型模板参数(例如“size_t”)会失败。有没有办法让我可以,例如只写:
void test(Foo auto xy);
我知道自从 C++20 以来,出现了一些其他方法来约束函数的模板参数,但是,有没有一种简短的方法可以说“我不在乎它如何专门化结构,只要它是吗?
没有。
无法编写适用于具有所有类型参数的模板和 std::array
(即您的 Foo
)之类的模板的通用 is_specialization_of
,因为无法编写采用任何 kind.
参数的模板
有一项语言功能提案允许 (P1985), but it's still just a proposal and it won't be in C++23. But it directly allows for a solution for this. Likewise, the reflection proposal (P1240) 提供一种方法来执行此操作(除了您必须拼写概念 Specializes<^Foo>
而不是 Specializes<Foo>
).
在这些事情发生之前,您要么为模板编写定制概念,要么重写模板以仅采用类型参数。
考虑这个例子:
#include <iostream>
template <typename T, std::size_t I>
struct Foo
{
};
template <typename T>
struct specializes_foo : std::false_type {};
template <typename T, std::size_t I>
struct specializes_foo<Foo<T, I>> : std::true_type {};
template <typename T>
concept foo = specializes_foo<T>::value;
int main()
{
std::cout << foo<int> << "\n";
std::cout << foo<Foo<int,3>> << "\n";
}
C++20 有更短的方法吗?我知道你可以为“专门化模板”做一个概念,例如:
// checks if a type T specializes a given template class template_class
// note: This only works with typename template parameters.
// e.g.: specializes<std::array<int, 3>, std::array> will yield a compilation error.
// workaround: add a specialization for std::array.
namespace specializes_impl
{
template <typename T, template <typename...> typename>
struct is_specialization_of : std::false_type {};
template <typename... Args, template <typename...> typename template_class>
struct is_specialization_of<template_class<Args...>, template_class> : std::true_type {};
}
template <typename T, template <typename...> typename template_class>
inline constexpr bool is_specialization_of_v = specializes_impl::is_specialization_of<T,template_class>::value;
template <typename T, template <typename...> typename template_class>
using is_specialization_of_t = specializes_impl::is_specialization_of<T,template_class>::type;
template<typename T, template <typename...> typename template_class>
concept specializes = is_specialization_of_v<T, template_class>;
但是,使用非类型模板参数(例如“size_t”)会失败。有没有办法让我可以,例如只写:
void test(Foo auto xy);
我知道自从 C++20 以来,出现了一些其他方法来约束函数的模板参数,但是,有没有一种简短的方法可以说“我不在乎它如何专门化结构,只要它是吗?
没有。
无法编写适用于具有所有类型参数的模板和 std::array
(即您的 Foo
)之类的模板的通用 is_specialization_of
,因为无法编写采用任何 kind.
有一项语言功能提案允许 (P1985), but it's still just a proposal and it won't be in C++23. But it directly allows for a solution for this. Likewise, the reflection proposal (P1240) 提供一种方法来执行此操作(除了您必须拼写概念 Specializes<^Foo>
而不是 Specializes<Foo>
).
在这些事情发生之前,您要么为模板编写定制概念,要么重写模板以仅采用类型参数。