sea*_*lus 4 c++ language-lawyer
甲相关的问题提供了一种类型无关的例子false中static_assert:
template<class T> void foo()
{
if constexpr(false)
static_assert(false);
}
Run Code Online (Sandbox Code Playgroud)
但是,我更担心同样的事情是否适用于依赖于类型的false. 这是标准中的相关引用:
如果不能为模板或模板中的 constexpr if 语句的子语句生成有效的特化,并且模板未实例化,则程序格式错误,无需诊断。§ 13.7/8.1
这让我感到惊讶,因为我经常看到以下习语:
template<class T> void foo()
{
if constexpr(cond)
// ...
else
static_assert(!std::is_same_v<T, T>);
}
Run Code Online (Sandbox Code Playgroud)
事实上,cppreference 甚至提供了一个同样的例子:
template<class T> struct dependent_false : std::false_type {};
template<class T> void foo()
{
if constexpr (cond)
// ...
else
static_assert(dependent_false<T>::value);
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,在这两种情况下,都无法为相关if constexpr子语句生成有效的专业化,因此格式不正确,不需要诊断。我对么?
无法为相关
if constexpr子语句生成有效的专业化
嗯,没有。
如果您dependent_false先进行专业化,则可以拥有该分支的有效专业化:
template <> struct dependent_false<int> : std::true_type {};
///
foo<int>(); // <-- A valid specialization for the `else` branch is possible here
Run Code Online (Sandbox Code Playgroud)
可以创建这样的专业化(即使您没有)这一事实使static_assert(dependent_false<T>::value);格式良好。
另一方面,static_assert(!std::is_same_v<T, T>);是格式错误的 NDR,因为std::不允许专门化模板。