c++ - constexpr if 和 static_assert

标签 c++ templates constexpr c++17 static-assert

P0292R1 constexpr ifincluded ,在 C++17 的轨道上。它看起来很有用(并且可以代替 SFINAE 的使用),但是关于 static_assert 的评论 格式错误,不需要诊断 在 false 分支中让我感到害怕:

Disarming static_assert declarations in the non-taken branch of a
constexpr if is not proposed.

void f() {
  if constexpr (false)
    static_assert(false);   // ill-formed
}

template<class T>
void g() {
  if constexpr (false)
    static_assert(false);   // ill-formed; no 
               // diagnostic required for template definition
}

我认为完全禁止在 constexpr if 中使用 static_assert (至少是 false/non-taken 分支,但这实际上意味着它不是安全或有用的事情)。

这是如何从标准文本中得出的?我发现提案措辞中没有提到 static_assert,C++14 constexpr 函数确实允许 static_assert (详情见 cppreference:constexpr)。

它是否隐藏在这个新句子中(6.4.1 之后)? :

When a constexpr if statement appears in a templated entity, during an instantiation of the enclosing template or generic lambda, a discarded statement is not instantiated.

从那以后,我假设它也被禁止,不需要诊断,调用其他 constexpr(模板)函数,在调用图中 somewhere 可能调用 static_assert .

底线:

如果我的理解是正确的,这不是对 constexpr if 的安全性和有用性施加了相当严格的限制,因为我们必须(从文档或代码检查中)知道任何使用static_assert?我的担心是不是放错了地方?

更新:

此代码编译时没有警告(clang head 3.9.0),但据我了解格式错误,不需要诊断。有效与否?

template< typename T>
constexpr void other_library_foo(){
    static_assert(std::is_same<T,int>::value);
}

template<class T>
void g() {
  if constexpr (false)
    other_library_foo<T>(); 
}

int main(){
    g<float>();
    g<int>();
}

最佳答案

这是在讨论一个成熟的模板规则——允许编译器诊断的相同规则template<class> void f() { return 1; } . [temp.res]/8新更改以粗体显示:

The program is ill-formed, no diagnostic required, if:

  • no valid specialization can be generated for a template or a substatement of a constexpr if statement ([stmt.if]) within a template and the template is not instantiated, or
  • [...]

无法为包含 static_assert 的模板生成有效的特化其条件不相关,计算结果为 false ,因此该程序是非良构 NDR。

static_assert s 具有可以评估为 true 的相关条件至少有一种类型不受影响。

关于c++ - constexpr if 和 static_assert,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38304847/

相关文章:

c++ - BigInt 实现 - 将字符串转换为存储为 unsigned int 的二进制表示

templates - 在模板命名空间前缀是未声明的 xsl 1.0

c++ - 如何在C++中有条件地编写依赖于lambda返回类型的代码?

c++ - 在包装类的枚举中定义静态 constexpr 值

c++ - 具有部分定义类的模板化 constexpr 函数调用会更改后续结果

c++ - 如何将纯文本文件作为命令行参数传递

c++ - 类中定义的静态成员函数是否隐式内联?

c++ - C++ 编程语言,第 5.9 章练习 1

c# - 模板抽象类在字典中有值

c++ - 有没有办法构造一个 constexpr 函数来获取 double 的位表示?