【问题标题】:using static_assert in a class - how?在类中使用 static_assert - 如何?
【发布时间】:2023-04-04 05:54:01
【问题描述】:

我试图简化在编译时检查一个值到新类型的转换是否保留了该值。 STL中可能有一些东西可以为我做到这一点,但我没有看到它,所以我写了一个。它可以工作,但我想将它转换为一个类,以使其对其他人的使用更简单。我无法让它工作,我觉得我错过了一些明显的东西。

这很好用:

    template <typename T, typename Q>
    constexpr bool checkV(const Q x) 
    {return x == (T)x && ((x < 0) == ((T)x < 0));}

    static_assert(checkV<unsigned int>(-7), "No");

但通话很笨拙,所以我想要更像

    CheckIt<unsigned int>(-7)

所以我尝试了

    template<typename T>
    class CheckIt {public:
      template<typename Q>
      constexpr CheckIt(const Q x) {static_assert(checkV<T>(x), "No");}
};

我尝试了 const 和 constexpr 的各种组合(发现参数不能是 constexpr,这很烦人)。我尝试的一切都会导致 g++ 抱怨 x 不是构造函数中的常量表达式。

我错过了什么? checkv 和构造函数都始终使用常量调用,例如 -7。 checkv() 很高兴在编译时进行评估,我看不出在哪里使用构造函数进行包装,这会给编译器增加任何额外的负担,但显然确实如此。注意我需要它在 C++11 中工作,但我看不出以后的版本会在哪里提供帮助。我在运行时使用断言检查没有问题,但我想要常量的编译时解决方案。 TIA。

【问题讨论】:

  • x 必须是模板参数。
  • 即使函数本身是常量表达式,您也错过了函数参数不是常量表达式。我想写 static_assert(checkV&lt;unsigned int&gt;(-7), "No"); 将是 c++11 的唯一选择
  • I want the compile time solution for constants - 所以要检测参数是否为常量,然后使用static_assert?如果它应该只是常量,请使用模板。
  • 这并没有解决问题,但在checkV 的正文中,除了两个强制转换中的括号外,所有括号都是多余的。
  • x 作为函数参数传递永远不会起作用,因为它是一个变量,而不是一个常量表达式。

标签: c++ static-assert


【解决方案1】:

将变量传递给函数将不起作用,因为它不是常量表达式,因此 static_assert 不会接受它。

您可以尝试将值作为模板参数传递。

template <typename T, typename Q>
constexpr bool checkV(const Q x)
{
    return x == static_cast<T>(x) && ((x < 0) == (static_cast<T>(x) < 0));
}

template <typename T, typename Q, Q N>
void CheckIt() {
    static_assert(checkV<T, Q>(N));
}


int main() {
    constexpr auto val = -7;
    CheckIt<unsigned int, decltype(val), val>();
}

但它并不干净。

编辑:您也可以使用“好”的旧宏

#define CheckIt(x,y) static_assert(checkV<x, decltype(y)>(y));

int main() {
    CheckIt(unsigned int, -7);
}

【讨论】:

  • 我认为我的问题是你不能使用 constexpr 来声明一个函数参数。如果编译器可以看到该值不是常量,我需要它工作,然后 SFINAE 允许该模板变体无害地失败。我明白为什么委员会从来没有增加对此的支持;这可能是唯一有用的情况。哦,好吧。
猜你喜欢
  • 2019-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多