Home > Net >  Static assert that a function returns a weakly ordered type
Static assert that a function returns a weakly ordered type

Time:09-17

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
}
  • Related