static_assert 与 SFINAE
static_assert with SFINAE
标准在[temp.res]/8中说:
No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required. ... [ Note: If a template is instantiated, errors will be diagnosed according to the other rules in this Standard. Exactly when these errors are diagnosed is a quality of implementation issue. — end note ]
我的问题是:以下是否算作可以生成的有效专业化?
#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");
(我们不能同时既不是 int
又是 int
时间),这是不允许的。另一方面,就 SFINAE 而言,类型(例如 A<double>
的格式非常好并且可以生成,但会立即引发静态断言失败。这目前在 GCC 8.3 中有效,但考虑到上面引用的标准中的“格式错误,不需要诊断”部分,我想确保它实际上 should 工作。 (注意:这里的工作被定义为如果我尝试实例化一个 A<double>
它会抛出一个 static assertion
失败,如果我不这样做则静默编译)
不,这不是工作的意思。那不是有效的 C++ 程序。
根据您引用的段落,部分专业化的模板定义是格式错误的 NDR。没有可能从中生成有效的专业化。
该标准通常将某些内容指定为格式错误的 NDR,因为在一般情况下对其进行可靠检查将等同于自相矛盾 Rice's theorem。所以编译器没有义务尝试,但他们可以尝试一些启发式分析或其他。
GCC 和 Clang 通常会在添加启发式方法后进行更多诊断。我不会试图声称“这是依赖的”作为反对的盾牌。代码本身从一开始就是无效的。
标准在[temp.res]/8中说:
No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required. ... [ Note: If a template is instantiated, errors will be diagnosed according to the other rules in this Standard. Exactly when these errors are diagnosed is a quality of implementation issue. — end note ]
我的问题是:以下是否算作可以生成的有效专业化?
#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");
(我们不能同时既不是 int
又是 int
时间),这是不允许的。另一方面,就 SFINAE 而言,类型(例如 A<double>
的格式非常好并且可以生成,但会立即引发静态断言失败。这目前在 GCC 8.3 中有效,但考虑到上面引用的标准中的“格式错误,不需要诊断”部分,我想确保它实际上 should 工作。 (注意:这里的工作被定义为如果我尝试实例化一个 A<double>
它会抛出一个 static assertion
失败,如果我不这样做则静默编译)
不,这不是工作的意思。那不是有效的 C++ 程序。
根据您引用的段落,部分专业化的模板定义是格式错误的 NDR。没有可能从中生成有效的专业化。
该标准通常将某些内容指定为格式错误的 NDR,因为在一般情况下对其进行可靠检查将等同于自相矛盾 Rice's theorem。所以编译器没有义务尝试,但他们可以尝试一些启发式分析或其他。
GCC 和 Clang 通常会在添加启发式方法后进行更多诊断。我不会试图声称“这是依赖的”作为反对的盾牌。代码本身从一开始就是无效的。