首页 > 解决方案 > 有没有办法在文字表达式与函数调用上进行静态断言?

问题描述

我有一个快速而肮脏的宏,用于快速测试我的程序:

#define ASSERT_EQUAL(expected, actualFunc, desc)

expected应该是第一个参数,并且是文字; actualFunc应该是第二个参数,并且是带参数的函数调用,示例调用如下所示:

ASSERT_EQUAL(true, test1(42), "cache-friendly");

在这个宏中,我还将计时第二个参数(函数调用),为了确保它按预期工作,我需要确保参数以正确的顺序传递,否则它应该出错。,如下所示:

ASSERT_EQUAL(test1(42), true, "cache-friendly");

我试过了:

static_assert(std::is_fundamental<decltype(expected)::value)

但它不起作用,因为即使我将函数调用作为第一个参数传入它也不会出错expected,因为它的返回值是一个基本类型。

如果参数的顺序不符合预期,有没有办法静态断言和出错?

仅供参考 - 宏实现:

static int CaseNum = 0;

#define ASSERT_BASE(expected, actualFunc, desc) \
  std::chrono::steady_clock clock;  \
  auto start = clock.now();  \
        auto actual = actualFunc; \
  auto elapsedTime = clock.now() - start; \
  auto timeInUS = std::chrono::duration_cast<std::chrono::microseconds>(elapsedTime).count(); \
  cout << boolalpha << "CASE " << ++CaseNum << ": " << "EXPECTED=" << expected  << "; ACTUAL=" << actual << "; elapsedTime=" << timeInUS << "us" <<  " --- " <<  desc << endl; \

#define ASSERT_EQUAL(expected, actualFunc, desc) \
{ \
  ASSERT_BASE(expected, actualFunc, desc) \
  assert(expected == actual); \
}

#define ASSERT_NEAR(expected, actualFunc, desc) \
{ \
  ASSERT_BASE(expected, actualFunc, desc) \
  assert(fabs(expected - actual) < 0.0001); \
}

标签: c++

解决方案


通过检查语言中的表达式实际上不可能做到这一点,因为 C++ 不断扩展常量表达式中允许的范围。您可以通过例如使用它来初始化变量来检查是否expected可以用作常量表达式,但是如果函数是,这可能constinit会导致假阴性,它很可能是。testconstexpr

相反,您可以使用预处理器“字符串化”运算符执行文本自省:

static_assert(std::string_view{#expected}.find('(') == std::string_view::npos, "expected must be a literal");

例子


推荐阅读