Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::common_类型的专门化-误解、bug、两者都有,还是两者都没有?_C++_C++17_Libstdc++_Libc++ - Fatal编程技术网

C++ std::common_类型的专门化-误解、bug、两者都有,还是两者都没有?

C++ std::common_类型的专门化-误解、bug、两者都有,还是两者都没有?,c++,c++17,libstdc++,libc++,C++,C++17,Libstdc++,Libc++,标记为C++17,因为这是我引用的规范版本 以下是国际海事组织标准的相关部分,第23.15.7.6节[meta.trans.other] 模板结构通用类型 除非该特性是专门化的(如下注B所述),否则 构件类型应按照以下注释A的规定进行定义或省略。 如果省略,则不应有构件类型。中的每种类型 参数包T应完整、cv无效或一系列未知参数 束缚 注一 3。注A:对于应用于类型参数包T的常见类型特征,构件类型应定义为或不存在,如下所示: (3.1)-如果……(T)的尺寸为零,则无构件类型 (3.2)-如果…

标记为C++17,因为这是我引用的规范版本

以下是国际海事组织标准的相关部分,第23.15.7.6节[meta.trans.other]

模板结构通用类型

除非该特性是专门化的(如下注B所述),否则 构件类型应按照以下注释A的规定进行定义或省略。 如果省略,则不应有构件类型。中的每种类型 参数包T应完整、cv无效或一系列未知参数 束缚

注一

3。注A:对于应用于类型参数包T的常见类型特征,构件类型应定义为或不存在,如下所示:

(3.1)-如果……(T)
的尺寸为零,则无构件类型

(3.2)-如果……(T)的尺寸为一,则T0表示构成包装T的唯一类型。构件类型定义名称类型应表示与
普通类型相同的类型(如有)否则不得有任何构件类型

(3.3)-如果……(T)
的大小是两个,那么让构成T的第一和第二类型分别用T1和T2表示,让D1和D2分别表示与
衰减T
衰减T
相同的类型

(3.3.1)-如果
是相同的
是相同的是错误的或
是相同的
是错误的,让C表示相同的类型,如果有的话,作为
普通类型

(3.3.2)-否则,让C表示相同类型(如有),如
decay\u t
[注:如果存在专门化
通用类型,则此项不适用。-结束注]

在任何一种情况下,成员类型DEF name type应表示与C相同的类型(如有)。否则,不应有成员类型

(3.4)-如果……(T)
的大小大于2,则T1、T2和R分别表示构成T的第一、第二和(一组)剩余类型。C表示与
普通类型\u T相同的类型(如有)。如果存在此类类型C,则成员类型定义名称类型应表示相同类型(如有),如
普通类型\u t
。否则,不得有任何构件类型

注意B

4。注B:尽管有23.15.2的规定,并且根据20.5.4.2.1,程序可以专门化T1和T2类型的
通用类型
,使得
是相同的
是相同的
都是正确的。[注:当模板参数之间只需要显式转换时,需要此类专门化。-结束注]

这种专门化不需要有一个名为type的成员,但如果有,则该成员应是一个可访问且明确无歧义的cv非引用类型C的typedef名称,其中T1和T2类型均显式可转换。此外,
common\u type\t
应表示与
common\u type\t
相同的类型(如有)。违反本说明规则不需要诊断

基于此,我希望通过以下断言(它们确实如此)

static_assert(不是std::is_const_v);
静态断言(不是std::is_volatile_v);
静态断言(std::is_same_v);
静态断言(std::is_same_v);
同样,我希望这些也能通过

使用D1=std::chrono::duration;
使用D2=std::chrono::duration;
静态断言(不是std::is_const_v);
静态断言(不是std::is_volatile_v);
静态断言(std::is_same_v);
静态断言(std::is_same_v);
但是,如果调用
std::common_type
,并在
std::chrono::duration
中添加任何cv限定符或引用,则会出现编译器错误

在我看来,该标准似乎表明第二组断言应该成功,但它们在clang和gcc中都失败了。因此,我假设我误读了标准——或者两个供应商都有相同的错误,这是不太可能的(另外,我总是在打赌谁错的时候跟着我)

也许“除非这一特征是专门化的(如下面注B所述)”这句话意味着注A第3.3节的承租人都没有申请专门化,但这意味着我们可以合法地以非常奇怪的结果结束。。。像是在请求时出现编译错误

使用D1=std::chrono::duration;
使用D2=std::chrono::duration;
静态断言(不是std::is_const_v);
正常使用
std::common_type
不需要在调用它之前删除cv限定符和引用,但似乎专门化可以要求调用方必须删除cv限定符和引用

这似乎是错的。。。某处。所以,我想弄明白。。。规范、供应商实现或我的头脑中是否存在错误


更新


编译器资源管理器中的gcc/trunk似乎成功地编译了我认为它应该编译的所有内容,尽管gcc 9.2失败了,而且所有的clang版本也失败了。

这似乎是您的系统中的一个bug。的当前版本不存在此缺陷,这可以从中得到证明


3.3.1是否要求其衰减参数并重新出现;不这样做。

@NathanOliver是的,但3.3.1规定,如果您传入一个
常量
版本,它应该衰减它(删除常量),并且
类型
字段是
通用类型
,它是专门化的。@yakAdamnevraumont是的。我只是回到过去。在我看来这是个bug。这不是一个编译器问题,而是一个标准库实现问题。libstdc++以前有一个bug,显然已经修复了。libc++拥有这种权利已经有一段时间了。(你说得对)。此外,您不必全力以赴使用chrono,您可以在macOS上使用clang/libc++和
-std=c++17
或更高版本为我完成您最后的示例编译godbolt上的构建示例