static_assert未初始化的具有有效专用化的模板类中
static_assert in not initialized template class with valid specialization
我的问题是,以下代码是否有效:
template<int i> class Class
{
static_assert(sizeof(i) == 0, "Class instantiated with i != 1");
};
template<> class Class<1> {};
此代码段使用g++
进行编译。但clang++
被static_assert
困住了:
error: static_assert failed "Class instantiated with non-int type"
使用类型而不是类似int
的模板
template<typename T> class Class
{
static_assert(sizeof(T) == 0, "Class instantiated with non-int type");
};
template<> class Class<int> {};
被两个编译器接受。完全相同的模式适用于函数模板。
我找到了 open-std.org::非依赖static_assert声明,但这似乎不适用,因为我的static_assert
依赖于模板参数。
您可以在 godbolt.org 上检查所描述的行为
编辑:正如Johan Lundberg在评论中指出的那样,我的问题错了。实际上,sizeof(i)
不依赖于模板参数。R.Sahu 也是完全正确的:断言i != 1
会更有意义。为此,两个编译器都接受代码。
但是,上面的示例仍然使用g++
进行编译。由于open-std.org::非依赖static_assert声明适用于这种情况(我再次为这方面的错误问题道歉):g++
编译代码而没有错误实际上是错误的吗?
clang++拒绝你的代码是正确的,但g++没有抓住错误并没有错;这是一个"不需要诊断"的情况。
该标准将模板中的表达式严格定义为"类型相关"和/或"值相关"。 给定template<int i>
,i
是值依赖的,但不依赖于类型。
[14.6.2.2/4]:以下形式的表达式从不依赖于类型(因为表达式的类型不能依赖于):
- 。
sizeof
一元表达式- 。
[14.6.2.3/2]:如果一元表达式或表达式依赖于类型或类型ID依赖于,则以下形式的表达式是值相关的:
sizeof
一元表达式- 。
所以sizeof(i)
不是依赖的。
最后,14.6/8 说:
如果紧跟在其定义之后的模板的假设实例化由于构造不依赖于模板参数而导致格式错误,则程序格式不正确;不需要诊断。
首先,如果要断言模板已使用错误的类型实例化,则必须在static_assert中明确:
#include <type_traits>
template<typename T> class Class
{
static_assert(std::is_same<T, int>::value, "Class instantiated with non-int type");
};
其次,以下行可能没有按照您的想法进行:
template<> class Class<int> {};
您在这里实际要做的是创建一个全新的专业化,这与默认的模板专业化Class<T>
没有任何关系。
删除int
的专用化并实例化默认专用化的非 int 类会在两个编译器中产生错误,因为它应该:
int main()
{
Class<int> ci;
Class<float> cf;
}
示例错误:
<source>: In instantiation of 'class Class<float>':
<source>:14:18: required from here
<source>:5:5: error: static assertion failed: Class instantiated with non-int type
static_assert(std::is_same<T, int>::value, "Class instantiated with non-int type");
^~~~~~~~~~~~~
- .cpp和.h文件中的模板专用化声明
- 欧拉项目#8答案是大以获得有效答案
- 调用专用模板时出错"no matching function for call to [...]"
- 调整大小后指向元素值的指针unordered_map有效?
- 模板专用化(按容器):value_type
- 为什么是0;C++中的有效语句
- 最高有效数字侧的第N位
- GCC对可能有效的代码抛出init list生存期警告
- 有效地使用std::unordered_map来插入或增加键的值
- c++中O(n^(1/3))中一个数的除数的有效计数
- 使用无符号字符数组有效存储内存
- 自定义先决条件对移动分配运算符有效吗
- 静态数据成员模板专用化的实例化点在哪里
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 有哪些有效的方法可以消除一组 100 万个字符串>重复数据?
- static_assert未初始化的具有有效专用化的模板类中
- 在不使用专用语法的情况下,为不同类型的不同方式实现模板类的方法是否有效C++?
- 类模板成员模板的成员模板的显式模板函数专用化有效吗
- boost bind.hpp 1.54 c++ 专用模板无法在 Solaris 上编译。有效C++?
- 在 C++14 中使用自动退货'type'进行显式模板专用化是否有效?