I am learning c++20 concepts and need help. I would like to print a message on stdout when the concept’s "requires" clause is not fulfilled. The concept as expected does not compile when the class BadObject does not have Print method, but I would like to provide an alternative template when the "requires" is not satisfied and in case of BadObject, it should print the "object has no Print method" message. It’s almost like negating the concept’s requires clause, maybe? Is there anyway to achieve this? Thank you!
#include <iostream>
template <typename T>
concept HasPrintMethod =
requires(T t) { { t.Print() } ;
};
struct GoodObject {
void Print() {
std::cout << "hello from the object!\n";
}
};
struct BadObject {};
template<typename T>
void PrintValue(T obj) {
if (HasPrintMethod<T>) {
obj.Print();
} else {
std::cout << "object has no Print method!\n";
}
}
int main(){
PrintValue(GoodObject());
// compile-time error as expected, how do I print "object has no Print method" to
//stdout
PrintValue(BadObject());
}
>Solution :
if constexpr is the missing piece in your own attempt
template<typename T>
void PrintValue(T obj) {
if constexpr (HasPrintMethod<T>) {
obj.Print();
} else {
std::cout << "object has no Print method!\n";
}
}
To make a long story short: even if the condition comes from a concept or other compile-time constant, a regular if will have both branches instantiated. On the other hand, a constexpr if is allowed to discard a branch if the template parameter doesn’t satisfy the condition.