#include <iostream>
#include <concepts>
struct Sound { int amplitude; };
struct Light { int brightness; };
template <typename T>
concept Alert = std::derived_from<T, Sound> && std::derived_from<T, Light>;
struct FirstSound : Sound{};
struct FirstLight : Light{};
struct FirstSoundLight : FirstSound, FirstLight{};
struct LastSound : Sound{};
struct LastLight : Light{};
struct LastSoundLight : LastSound, LastLight{};
template <typename T>
concept FirstAlert = std::derived_from<T, FirstSound> && std::derived_from<T, FirstLight>;
template <typename T>
concept LastAlert = std::derived_from<T, LastSound> && std::derived_from<T, LastLight>;
void warn(FirstAlert auto const& a, LastAlert auto const& b)
{ std::cout << "Special warning"; }
void warn(Alert auto const& a, LastAlert auto const& b) = delete;
//{ std::cout << "Deleted warning"; }
void warn(Alert auto const& a, Alert auto const& b)
{ std::cout << "General warning"; }
int main()
{
warn(FirstSoundLight{}, LastSoundLight{});
return 0;
}
The code above is a simplified version of my problem. How can I make the compiler select functions unambigiously in the given order without explicitly casting the parameters?
#include <iostream>
#include <concepts>
struct Sound { int amplitude; };
struct Light { int brightness; };
template <typename T>
concept Alert = std::derived_from<T, Sound> && std::derived_from<T, Light>;
struct FirstSound : Sound{};
struct FirstLight : Light{};
struct FirstSoundLight : FirstSound, FirstLight{};
struct LastSound : Sound{};
struct LastLight : Light{};
struct LastSoundLight : LastSound, LastLight{};
template <typename T>
concept FirstAlert = std::derived_from<T, FirstSound> && std::derived_from<T, FirstLight>;
template <typename T>
concept LastAlert = std::derived_from<T, LastSound> && std::derived_from<T, LastLight>;
void warn(FirstAlert auto const& a, LastAlert auto const& b)
{ std::cout << "Special warning"; }
void warn(Alert auto const& a, LastAlert auto const& b) = delete;
//{ std::cout << "Deleted warning"; }
void warn(Alert auto const& a, Alert auto const& b)
{ std::cout << "General warning"; }
int main()
{
warn(FirstSoundLight{}, LastSoundLight{});
return 0;
}
The code above is a simplified version of my problem. How can I make the compiler select functions unambigiously in the given order without explicitly casting the parameters?
Share Improve this question edited Feb 17 at 21:20 Eugene 7,6881 gold badge25 silver badges35 bronze badges asked Feb 17 at 21:02 ahfaktahfakt 435 bronze badges1 Answer
Reset to default 3You need to subsume concept Alert
in your 2 other concepts:
template <typename T>
concept FirstAlert = Alert<T> && std::derived_from<T, FirstSound> && std::derived_from<T, FirstLight>;
template <typename T>
concept LastAlert = Alert<T> && std::derived_from<T, LastSound> && std::derived_from<T, LastLight>;