微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 SFINAE 的 static_assert

如何解决使用 SFINAE 的 static_assert

标准在 [temp.res]/8 中说:

对于可以生成有效专业化的模板定义,不应发出任何诊断。如果无法为模板定义生成有效的专业化,并且该模板未实例化,则模板定义格式错误,无需诊断。 ... [ 注意:如果模板被实例化,错误将根据本标准中的其他规则进行诊断。准确地诊断出这些错误是实施质量问题。 — 尾注 ]

我的问题是:以下是否算作可以生成的有效专业化?

#include <type_traits>

template <typename T,typename Enable = void>
class A;

template <typename T>
class A<T,typename std::enable_if<not std::is_same<T,int>::value>::type>
{
public:
    static_assert(std::is_same<T,int>::value,"should not be here!");
};

一方面,static_assert 本质上相当于 static_assert(false,"should not be here");(我们不能同时成为 intint) ,这是不允许的。另一方面,就 SFINAE 而言,类型,例如 A<double> 的格式非常好,可以生成,但会立即引发静态断言失败。这目前在 GCC 8.3 中有效,但鉴于上述标准引用的“格式错误,无需诊断”部分,我想确保它确实应该工作. (注意:这里的工作被定义为表示如果我尝试实例化 static assertion 则它会抛出 A<double> 失败,如果我不实例化则静编译)

解决方法

不,它不是意在工作的。这不是一个有效的 C++ 程序。

根据您引用的段落,您的部分专业化的模板定义是格式错误的 NDR。没有可以从中生成的有效特化。

该标准通常将某些内容指定为格式错误的 NDR,因为在一般情况下对其进行可靠检查相当于与 Rice's theorem 相矛盾。所以编译器没有义务尝试,但他们可能尝试一些启发式分析或其他。

GCC 和 Clang 经常会在添加启发式方法后进行更多诊断。我不会试图声称“这是依赖”作为反对的盾牌。代码本身从一开始就无效。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。