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.
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;};