Date: Sun, 15 Mar 2026 00:49:54 -0400
Would fold expressions make this more readable?
```cpp
template<typename T, typename... Ts>
concept any_of = (std::same_as<T, Ts> || ...);
template<typename T>
concept natural_number = any_of<T, unsigned char, unsigned short,
unsigned int, unsigned long,
unsigned long long>;
```
On Sat, Mar 14, 2026, 7:13 a.m. Emanuel Spiridon via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> C++ currently has no way to create a named and reusable set of types that
> can be used as a concept constraint. Every time you write a concept
> constraint or requires section, you must enumerate the types, which makes
> large constraints unreadable and unmaintainable.
>
> I propose a solution, a type with template arguments for any type,
> including user-defined types and standard library types, which you can then
> use when creating a concept or requires section, by stating the named type
> list and the type you want to check.
>
> Here is how my implementation works:
>
> template<typename T>
> requires std::is_same_v<T, unsigned char> || std::is_same_v<T, unsigned short> || std::is_same_v<T, unsigned int> || std::is_same_v<T, unsigned long> || std::is_same_v<T, unsigned long long>void natural_only(T);template<typename T>
> requires std::is_same_v<T, unsigned char> || std::is_same_v<T, unsigned short> || std::is_same_v<T, unsigned int> || std::is_same_v<T, unsigned long> || std::is_same_v<T, unsigned long long> || std::is_same_v<T, char> || std::is_same_v<T, short> || std::is_same_v<T, int> || std::is_same_v<T, long> || std::is_same_v<T, long long>void whole_only(T);
> using natural_numbers = typename tag::merge_tags_and_types<unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>::type;using whole_numbers = typename tag::merge_tags_and_types<signed char, short, int, long, long long, natural_numbers>::type;using real_numbers = typename tag::merge_tags_and_types<float, double, long double>::type;using numbers = typename tag::merge_tags_and_types<whole_numbers, real_numbers>::type;
> template<typename T>concept is_number = tag::contains<numbers, T>;
> template<typename T>concept is_whole = tag::contains<whole_numbers, T>;
> template<typename T>concept is_natural = tag::contains<natural_numbers, T>;
> template<typename T>concept is_real = tag::contains<real_numbers, T>;
> template<typename T>
> requires tag::contains<natural_numbers, T>void natural_only(T);
>
> You can read the source of the implementation at Github
> <https://github.com/progress-3325/tagging>. A paper draft is forthcoming
>
> I am looking for feedback before submitting a formal paper.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
```cpp
template<typename T, typename... Ts>
concept any_of = (std::same_as<T, Ts> || ...);
template<typename T>
concept natural_number = any_of<T, unsigned char, unsigned short,
unsigned int, unsigned long,
unsigned long long>;
```
On Sat, Mar 14, 2026, 7:13 a.m. Emanuel Spiridon via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> C++ currently has no way to create a named and reusable set of types that
> can be used as a concept constraint. Every time you write a concept
> constraint or requires section, you must enumerate the types, which makes
> large constraints unreadable and unmaintainable.
>
> I propose a solution, a type with template arguments for any type,
> including user-defined types and standard library types, which you can then
> use when creating a concept or requires section, by stating the named type
> list and the type you want to check.
>
> Here is how my implementation works:
>
> template<typename T>
> requires std::is_same_v<T, unsigned char> || std::is_same_v<T, unsigned short> || std::is_same_v<T, unsigned int> || std::is_same_v<T, unsigned long> || std::is_same_v<T, unsigned long long>void natural_only(T);template<typename T>
> requires std::is_same_v<T, unsigned char> || std::is_same_v<T, unsigned short> || std::is_same_v<T, unsigned int> || std::is_same_v<T, unsigned long> || std::is_same_v<T, unsigned long long> || std::is_same_v<T, char> || std::is_same_v<T, short> || std::is_same_v<T, int> || std::is_same_v<T, long> || std::is_same_v<T, long long>void whole_only(T);
> using natural_numbers = typename tag::merge_tags_and_types<unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>::type;using whole_numbers = typename tag::merge_tags_and_types<signed char, short, int, long, long long, natural_numbers>::type;using real_numbers = typename tag::merge_tags_and_types<float, double, long double>::type;using numbers = typename tag::merge_tags_and_types<whole_numbers, real_numbers>::type;
> template<typename T>concept is_number = tag::contains<numbers, T>;
> template<typename T>concept is_whole = tag::contains<whole_numbers, T>;
> template<typename T>concept is_natural = tag::contains<natural_numbers, T>;
> template<typename T>concept is_real = tag::contains<real_numbers, T>;
> template<typename T>
> requires tag::contains<natural_numbers, T>void natural_only(T);
>
> You can read the source of the implementation at Github
> <https://github.com/progress-3325/tagging>. A paper draft is forthcoming
>
> I am looking for feedback before submitting a formal paper.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2026-03-15 04:50:09
