Using C++ concepts, I'd like to be able to define concepts that force all the types in a parameter pack to either be a given type, or in a list of given types. The 4 concepts I've defined are:
type_is: check if typeTmatches typeUtype_in: check if typeTis one of the types inU...all_types_are: check if all types in parameter packT...match typeUall_types_in: check if all types in parameter packT...are any of the types inU...(can be different types inU...)
The code, with a method for each concept to test agsinst:
#include <concepts>
#include <iostream>
#include <type_traits>
class A{public: int var = 100;};
class B{public: int var = 200;};
class C{public: int var = 300;};
template <typename TypeToCheck, typename TypeToCheckAgainst>
concept type_is = requires
{
requires std::same_as<std::remove_cvref_t<TypeToCheck>, TypeToCheckAgainst>;
};
template <typename TypeToCheck, typename ...TypesToCheckAgainst>
concept type_in = requires
{
requires (std::same_as<std::remove_cvref_t<TypeToCheck>, TypesToCheckAgainst> || ...);
};
template <typename ...TypesToCheck, typename TypeToCheckAgainst>
concept all_types_are = requires
{
requires (std::same_as<std::remove_cvref_t<TypeToCheckAgainst>, TypesToCheck> && ...);
};
template <typename ...TypesToCheck, typename ...TypesToCheckAgainst>
concept all_types_in = requires
{
requires (std::same_as<std::remove_cvref_t<TypesToCheck>, TypesToCheckAgainst> || ...);
};
auto method1(type_is<A> auto&& object)
{
std::cout << object.var;
std::cout << std::endl;
}
auto method2(type_in<A, B> auto&& object)
{
std::cout << object.var;
std::cout << std::endl;
}
auto method3(all_types_are<A> auto&&... objects)
{
(std::cout << ... << objects.var);
std::cout << std::endl;
}
auto method4(all_types_in<A, B> auto&&... objects)
{
(std::cout << ... << objects.var);
std::cout << std::endl;
}
int main()
{
A a;
B b;
C c;
method1(a);
method2(b);
method3(a, a, a);
method4(a, b, b);
return 0;
}
The first 2 concepts that check for a single type T work fine, but for the last 2 concepts, if I call methods constrained with those concepts, with arguments that should conform to the concepts, they still fail with:
main.cpp(75): error C2672: 'method3': no matching overloaded function found
main.cpp(75): error C7602: 'method3': the associated constraints are not satisfied
main.cpp(53): note: see declaration of 'method3'
main.cpp(76): error C2672: 'method4': no matching overloaded function found
main.cpp(76): error C7602: 'method4': the associated constraints are not satisfied
main.cpp(60): note: see declaration of 'method4'
I'm not sure how to correct my last two concepts so that they behave as desired, as I don't understand how the constraints aren't satisfied. What do I need to change in order to make the concepts work?