使用模板在size_t和int之间进行隐式类型转换
Implicit type conversion between size_t and int using templates
我有一个编译时序列生成类(取自此处,并对其进行了一点修改(:
#include <cstddef>
template <int...>
struct sequence {};
template <int... Ns>
struct generator;
template <std::size_t Count, int... Ns> // XXX (read below)
struct generator<Count, Ns...> {
using type = typename generator<Count - 1, Count - 1, Ns...>::type;
};
template <int... Ns>
struct generator<0, Ns...> {
using type = sequence<Ns...>;
};
template <std::size_t N>
using sequence_t = typename generator<N>::type;
int main() {
sequence_t<5> a;
return 0;
}
这在Visual Studio下编译良好(即使使用/permissive-
开关(。但它在GCC下抛出错误:
g++: error: template argument '(int)Count' involves template parameter(s)
g++: struct generator<Count, Ns...> {
...
它也在Clang下抛出错误:
clang++: error: ambiguous partial specializations of 'generator<0, 0, 1, 2, 3, 4>'
clang++: using type = typename generator<Count - 1, Count - 1, Ns...>::type;
...
clang++: note: partial specialization matches [with Count = 0, Ns = <0, 1, 2, 3, 4>]
clang++: struct generator<Count, Ns...> {
clang++:
clang++: note: partial specialization matches [with Ns = <0, 1, 2, 3, 4>]
clang++: struct generator<0, Ns...> {
在将标记行中的size_t
类型(标记为XXX (read below)
(更改为int
之后,每个人都正确地编译了此示例代码。
在这种情况下谁是对的?Visual Studio是因为它编译代码,还是GCC+Clang是因为它不允许编译代码?
为什么Visual Studio能够很好地编译示例?它是否比其他编译器有更宽松的隐式转换规则?还是有不同的原因?任何能让我指向文件的链接,如果能帮助我解码这些错误消息,也将不胜感激:(
这是由于活动语言缺陷CWG问题1647:
标准似乎对部分专业化中的非类型模板参数的类型是否必须与主模板的类型相同或是否允许转换保持沉默
在处理此问题时存在实施差异。。。
因此,这里没有合适的编译器,因为标准中不存在如何处理此类专业化的明确要求。
请注意,GCC和Clang由于不同的原因而偏离并未能通过本示例。演示:https://gcc.godbolt.org/z/41cbPePPW
Clang不喜欢两种专业中的一种:
error: ambiguous partial specializations of 'generator<0, 0, 1, 2, 3, 4>'
GCC完全忽略了struct generator<Count, Ns...>
试图实例化主模板的专业化,但由于缺乏其定义而失败:
error: invalid use of incomplete type 'struct generator<5>'
GCC在2014年报告了相应的错误(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60679)并且目前正在等待C++标准的澄清。
正如问题所说,用int
替换size_t
在这里是最好的,可以解决所有问题,演示:https://gcc.godbolt.org/z/fY9hxsT7P
- int(c) 和 c-'0' 之间的区别。C++
- 结构体 S { int align; } 之间的区别;(struct 关键字后的名称)和 struct { int al
- int x 和 int x=0 之间的差异在C++
- 在 C++11 中利用 int*_t、int_fast*_t 和 int_least*_t 之间的差异的一个很好的例子是
- ((int) a) 和 (int(a)) 之间的区别是什么?
- 在 C 和 C++ 中作为函数参数,int **a 和 int a[][] 之间有什么确切的区别
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 无符号长整型和无符号 int 之间有什么区别,这 2 种类型应该如何在 c# 中封送?
- 使用模板在size_t和int之间进行隐式类型转换
- int (%d) 和 %.0lf 之间有什么区别?
- 在 ENG US 和 ENG INT 之间切换时,GetKeyboardLayout() 不会改变
- 使用 double 在 C++ 中初始化 int 之间的差异
- 如何在 int 和 pair 之间C++进行unordered_multimap?
- 作为 int 传递和类内部指针之间的差异给我带来了分段错误
- 为什么 int 对象和函数类型之间不明确?
- int main()和签名main()之间的差异
- OpenMP增量在线程之间添加int
- C :使用函数过载与CHAR到INT之间的隐式转换,反之亦然
- 如何在-120到120之间更改int到char(或其他简单保存为一个字节的简单方法)
- React Native 0.40.0:指针和零之间的有序比较("NSNumber *"和"int")