检查表达式是否编译包括所有隐式转换
Check if an expression compiles including all implicit conversion
考虑以下代码:
void f(auto& i, auto& j)
{
static_assert(/* SOMETHING */, "");
// function body here...
}
我希望 /* SOMETHING */
部分检查以下代码是否编译(考虑到所有标准规则,如隐式转换规则):
i += j;
我试过了:
sizeof(std::declval<decltype(i)>() += std::declval<decltype(j)>());
但是失败了。
正确的做法是什么?
编辑:我知道 SFINAE 和约束模板参数。这不是问题的主题。主题是如何在测试表达式的正确性时使 static_assert
失败。
您必须定义相应的特征并在断言中使用它。例如
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{};
或者,如果概念可用,
template <typename A, typename B>
concept bool check = requires (A& a, B& b) {a += b;};
考虑以下代码:
void f(auto& i, auto& j)
{
static_assert(/* SOMETHING */, "");
// function body here...
}
我希望 /* SOMETHING */
部分检查以下代码是否编译(考虑到所有标准规则,如隐式转换规则):
i += j;
我试过了:
sizeof(std::declval<decltype(i)>() += std::declval<decltype(j)>());
但是失败了。
正确的做法是什么?
编辑:我知道 SFINAE 和约束模板参数。这不是问题的主题。主题是如何在测试表达式的正确性时使 static_assert
失败。
您必须定义相应的特征并在断言中使用它。例如
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{};
或者,如果概念可用,
template <typename A, typename B>
concept bool check = requires (A& a, B& b) {a += b;};