【发布时间】:2016-11-13 06:38:48
【问题描述】:
P0292R1 constexpr if 一直是included,正朝着 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(至少是错误/未采用的分支,但实际上这意味着它不是安全或有用的事情)。
这是如何从标准文本中得出的?我发现提案措辞中没有提到static_assert,C++14 constexpr 函数确实允许static_assert(详情参见cppreference:constexpr)。
它是否隐藏在这个新句子中(6.4.1 之后)? :
当 constexpr if 语句出现在模板化实体中时, 在封闭模板或通用 lambda 的实例化期间, 丢弃的语句不会被实例化。
从那时起,我假设它也被禁止,无需诊断,调用其他 constexpr(模板)函数,在调用图中某处可能调用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>();
}
【问题讨论】:
-
格式不正确,因为条件为假。不是因为它在一个 constexpr if...
-
@immibis。很明显,这都是关于未采取的分支,所以我不明白你的具体意思。是否愿意根据底线问题详细说明和解释?
-
@cpplearner,完成了,但它并没有增加太多。问题在于标准的内容及其含义。
-
目前还没有包含
if constexpr措辞的标准或标准草案,而被接受的论文P0292R2也尚未公开。 -
@immibis: "但是 constexpr if(false) 会删除其中的代码。" 就是这样:它不会删除代码在未采取的分支内。它使它们成为被丢弃的语句。有区别。
标签: c++ templates constexpr c++17 static-assert