【问题标题】:Check if an expression compiles including all implicit conversion检查表达式是否编译,包括所有隐式转换
【发布时间】:2015-09-22 20:51:48
【问题描述】:

考虑以下代码:

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 失败。

【问题讨论】:

  • 您可以查询的最佳结果是“这个表达式在被视为未计算的操作数时是否格式正确”,而不是“这个表达式是否会编译”。
  • @T.C.在这种情况下,这些语句之间没有有效的区别,AFAICS。
  • @Columbo 想想一个 += 模板,它的主体不能编译。
  • @T.C.好点子。我错过了在未评估的操作数中不需要该模板的实例化。

标签: c++ c++11 implicit-conversion compile-time static-assert


【解决方案1】:

您必须定义一个相应的特征并在断言中使用它。例如

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

【讨论】:

  • 我不知道 auto 函数参数在标准 C++ 中是允许的(我的意思是在 lambdas 之外)
  • @Brian 他们现在还没有,但是将包含在 C++1Z 中的 Concepts TS 使其有效(并且 GCC 实现了 4.9 的自动参数位)
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 2012-05-14
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多