标签:static-assert c language-lawyer
参见英文答案 > static_assert dependent on non-type template parameter (different behavior on gcc and clang) 2个
在模板中提供static_assert通常很有帮助.在模板不应该以某种方式实例化的情况下,我经常这样做
template<typename T, typename = void>
struct S
{
static_assert(false, "Unconditional error");
static_assert(sizeof(T) != sizeof(T), "Error on instantiation");
};
template<typename T>
struct S<T, std::enable_if_t<std::is_integral_v<T>>>
{
// ...
};
即使没有S的实例化,第一个static_assert也会立即失败,而如果没有实例化将导致主模板,则第二个将成功.
第二个static_assert显然是一个重言式,但它“依赖”T,以达到预期的效果.但这有保证吗?是否允许编译器评估这些重言式?
解决方法:
相关规则是[temp.res]/8:
Knowing which names are type names allows the syntax of every template to be checked. 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 within a template and the template is not instantiated, or
[…]
示例中的static_asserts都会导致程序格式错误,但不需要诊断.当然,允许编译器评估任意复杂的表达式,以试图证明不能生成有效的特化,但并不要求它们这样做. false肯定是一个容易立即验证的案例,所以它被诊断出来就不足为奇了.
始终发布诊断的一种常见方法是:
// never specialize me!
template <typename T>
struct always_false : std::false_type { };
template <typename T>
constexpr bool always_false_v = always_false<T>::value;
template<typename T, typename = void>
struct S {
static_assert(always_false_v<T>, "Unconditional error");
};
always_false可以假设专门针对特定的T来产生true_type,因此可以假设有效的特化S< T>.但是不要让任何人真正这样做.
标签:static-assert,c,language-lawyer 来源: https://codeday.me/bug/20191006/1861120.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。