constexpr if和static_assert [英] constexpr if and static_assert

查看:114
本文介绍了constexpr if和static_assert的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

P0292R1 constexpr(如果已包含,对于C ++ 17而言,该计划已步入正轨。似乎有用(并且可以替代SFINAE的用法),但是有关错误分支中的 static_assert 格式错误,无需诊断的注释我:

 如果不建议在
constexpr的未使用分支中撤消static_assert声明。

void f(){
如果constexpr(false)
static_assert(false); //格式错误的
}

template< class T>
void g(){
if constexpr(false)
static_assert(false); //格式错误;否
//模板定义需要诊断
}

我认为完全禁止在constexpr中使用 static_assert 如果(至少是false /不带分支,但这实际上意味着这样做不是安全或有用的事情)。 / p>

这是如何从标准文字中得出的?我发现在提案措辞中没有提及 static_assert ,C ++ 14 constexpr函数确实允许 static_assert (详细信息请参见cppreference: constexpr )。



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


当constexpr if语句出现在模板实体中时,在封装模板或通用lambda的实例化过程中,
b $ ba丢弃的语句未实例化。


从那以后,我假设它也是禁止的,不需要诊断,就可以调用调用图上的某处的其他constexpr(模板)函数可能会调用 static_assert



底线:



如果我的理解是正确的,那不是吗对 constexpr if 的安全性和实用性设置了相当严格的限制,因为我们必须(从文档或代码检查中知道)有关任何使用 static_assert的信息



更新:



此代码无需警告即可编译( clang head 3.9.0),但据我了解病状,无需诊断。有效吗?

  template<类型名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>的同一规则。无效f(){返回1; } [temp.res] / 8 ,新的更改以粗体显示:


该程序格式错误,无需诊断,如果:




  • 否可以为
    模板中的模板 constexpr if 语句([stmt.if])的子语句
    生成有效的专业化
    并且模板未实例化,或者

  • [...]


对于包含 static_assert 且条件独立且评估为 false ,因此程序是格式错误的NDR。



static_assert s具有从属条件,可以至少有一种类型的计算结果为 true


P0292R1 constexpr if has been included, on track for C++17. It seems useful (and can replace use of SFINAE), but a comment regarding static_assert being ill-formed, no diagnostic required in the false branch scares me:

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
}

I take it that it's completely forbidden to use static_assert inside constexpr if (at least the false / non-taken branch, but that in practice means it's not a safe or useful thing to do).

How does this come about from the standard text? I find no mentioning of static_assert in the proposal wording, and C++14 constexpr functions do allow static_assert (details at cppreference: constexpr).

Is it hiding in this new sentence (after 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.

From there on, I assume that it is also forbidden, no diagnostic required, to call other constexpr (template) functions which somewhere down the call graph may call static_assert.

Bottom line:

If my understanding is correct, doesn't that put a quite hard limit on the safety and usefulness of constexpr if as we would have to know (from documentation or code inspection) about any use of static_assert? Are my worries misplaced?

Update:

This code compiles without warning (clang head 3.9.0) but is to my understanding ill-formed, no diagnostic required. Valid or not?

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

解决方案

This is talking about a well-established rule for templates - the same rule that allows compilers to diagnose template<class> void f() { return 1; }. [temp.res]/8 with the new change bolded:

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
  • [...]

No valid specialization can be generated for a template containing static_assert whose condition is nondependent and evaluates to false, so the program is ill-formed NDR.

static_asserts with a dependent condition that can evaluate to true for at least one type are not affected.

这篇关于constexpr if和static_assert的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆