零大小数组不适用于模板
Zero-sized arrays don't work with templates
使用GCC,对于零大小的数组,模板参数替换似乎总是失败。我希望static_assert
失败,并在test1
中打印消息,就像在test2
中一样
您也可以删除static_assert
,该模板不适用于零大小的数组。
由于零大小数组是一个扩展,在C++标准中肯定没有对它们进行特殊处理的规则,所以我的问题是:
我错过了什么吗,这是一个错误,还是GCC作者有意这样做
#include <iostream>
template <size_t len>
void test1(const char(&arr)[len])
{
static_assert(len > 0, "why am I never printed?");
}
template <size_t len>
void test2(const char(&arr)[len])
{
static_assert(len > 10, "I will be printed");
}
int main()
{
char arr5[5];
test2(arr5);
char arr0[0];
test1(arr0);
}
错误输出:
main.cpp: In function ‘int main()’:
main.cpp:21:15: error: no matching function for call to ‘test1(char [0])’
test1(arr0);
^
main.cpp:21:15: note: candidate is:
main.cpp:4:6: note: template<unsigned int len> void test1(const char (&)[len])
void test1(const char(&arr)[len])
^
main.cpp:4:6: note: template argument deduction/substitution failed:
main.cpp: In instantiation of ‘void test2(const char (&)[len]) [with unsigned int len = 5u]’:
main.cpp:18:15: required from here
main.cpp:12:5: error: static assertion failed: I will be printed
static_assert(len > 10, "I will be printed");
^
我的编译器版本是:
g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
更新:我今天用Visual C++2015测试了它,它显示出了相同的行为。只有当零大小数组是类/结构的最后一个成员时,VC++才支持它们,但如果代码相应地更改,则与g++完全相同:
函数模板从不使用零大小的数组进行编译。为什么?
#include <iostream>
struct s_arr
{
char arr0[0];
};
template <size_t len>
void test(const char(&arr)[len])
{
}
int main()
{
s_arr s;
test1(s.arr0);
}
我错过了什么吗,这是一个bug,还是GCC作者有意这样做?
在模板中接受零大小的数组将导致一致性问题或不可能维护的语言。
给定
template <int N> void f(char (*)[N], int);
template <int N> void f(void *, void *);
调用f<1>(0, 0)
必须使用第一个重载,因为它与第二个参数更匹配。
调用f<0>(0, 0)
必须使用第二个重载,因为SFINAE由于数组大小为零而丢弃了第一个重载。
零大小数组可以作为扩展,只要它们不改变任何标准C++程序的语义。在模板参数替换期间允许零大小的数组将改变标准C++程序的语义,除非在不允许零大小数组的情况下实现了一整列异常。
相关文章:
- OpenGL - 在 NDC 中计算位置适用于着色器,但不适用于'regular'程序
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 如何修复我的最大公约数代码?它适用于除零和零以外的所有数字
- 选择排序C++(已修改)并非适用于所有情况
- 无法让"std::enable_if"适用于无作用域枚举
- 请找出我的代码中的错误,它在提交得到错误答案的同时仍然适用于我的所有测试用例
- 确定夏令时是否适用于特定日期
- 是否有一种 STL 算法可以最后找到,但它也适用于指针?
- 十进制到二进制的实现不能完全适用于我大学的检查器。问题或提示可能是什么
- 使用程序集嵌入数据时"Undefined reference"错误,使用适用于窗口的 mingw-w64 编译(COFF 而不是 ELF)
- 为什么 std::vector 适用于类定义中的不完整类型?
- 为什么哈希<常量字符*>适用于字符串而不是字符串变量?
- Lambda适用于最新的Visual Studio,但在其他地方不起作用
- 我该如何文档文档以使文档适用于类成员而不是匿名类型
- 计算 c# 中二进制文件符号的频率不起作用,但适用于等效的 c++ 代码
- 为什么 fstream.open(文件名) 适用于文字而不是生成的字符串?
- 模板重载和 SFINAE 仅适用于函数而不是类
- 为什么链接器不抱怨多个函数定义(仅适用于模板化函数)
- 我可以使用' == '来比较两个向量吗?我试过了,似乎工作正常。但我不知道它是否适用于更复杂的情况
- 延长临时的生命周期,适用于块范围的聚合,但不是通过"新";为什么?