Minimal example:
template <typename TFunc>
void func(TFunc f)
{
//Do something like:
double x{1}, y{2};
bool z = f(x) < f(y); //Do comparison somewhere
}
I would like to add a static_assert to the function that checks that f(x) returns a type where std::less computes. In other words I would like f(x) < f(y)
to compile. I am currently doing something like this:
static_assert((decltype(f(0)){} < decltype(f(0)){}) == false, "Function f must return a weakly ordered type.");
But here I assume that the function returns a type that can be default initialized. Is there a better way to check this?
CodePudding user response:
More complicated piece of code, but this seems more general way to check this, in case somebody else needs this:
template <typename T>
class is_weakly_ordered_type
{
private:
typedef int yes[1];
typedef int no[2];
template <typename S>
static yes& test(decltype(std::declval<S>() < std::declval<S>())) {};
template <typename S>
static no& test(...) {};
public:
static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
};
template <typename TFunc, typename ... TArgs>
class returns_weakly_ordered_type
{
private:
using TFuncRef = TFunc&;
using return_type = typename std::result_of<TFuncRef(TArgs...)>::type;
public:
static const bool value = is_weakly_ordered_type<return_type>::value;
};
Now you can do
template <typename TFunc>
void func(TFunc f)
{
static_assert(returns_weakly_ordered_type<decltype(func), double>::value, "Function func should return a weakly ordered type.");
//Do something like:
double x{1}, y{2};
bool z = f(x) < f(y); //Do comparison somewhere
}