Search code examples
c++c++11implicit-conversioncompile-timestatic-assert

Check if an expression compiles including all implicit conversion


Consider the following code:

void f(auto& i, auto& j)
{
    static_assert(/* SOMETHING */, "");
    // function body here...
}

I want the /* SOMETHING */ part to check whether the following code compiles (taking into account all the standard rules, like implicit conversion rules):

i += j;

I tried:

sizeof(std::declval<decltype(i)>() += std::declval<decltype(j)>());

but it fails.

What is the correct way to do it?

Edit: I know about SFINAE and constraining template parameters. This is not the topic of the question. The topic is how to make a static_assert fails while testing the correctness of an expression.


Solution

  • You'll have to define a corresponding trait and employ that in the assertion. E.g.

    template <typename A, typename B, typename=void> struct check : std::false_type{};
    template <typename A, typename B>
    struct check<A, B, std::void_t<decltype(std::declval<A&>() += std::declval<B&>())>>
        : std::true_type{};
    

    Or, if concepts are available,

    template <typename A, typename B>
    concept bool check = requires (A& a, B& b) {a += b;};