Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.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++ 叮当作响';s libc++;:在std::chrono::duration的定义中使用long-long_C++_C++11_Clang_Libc++ - Fatal编程技术网

C++ 叮当作响';s libc++;:在std::chrono::duration的定义中使用long-long

C++ 叮当作响';s libc++;:在std::chrono::duration的定义中使用long-long,c++,c++11,clang,libc++,C++,C++11,Clang,Libc++,在32位平台上的libc++中,int64\t被定义为long的别名。在64位平台上:long 另一方面,在定义std::chrono::duration别名时,您可以发现long-long被随意使用: typedef duration<long long, nano> nanoseconds; typedef duration<long long, micro> microseconds; typedef duration<long

在32位平台上的libc++中,
int64\t
被定义为
long
的别名。在64位平台上:
long

另一方面,在定义
std::chrono::duration
别名时,您可以发现
long-long
被随意使用:

typedef duration<long long,         nano> nanoseconds;
typedef duration<long long,        micro> microseconds;
typedef duration<long long,        milli> milliseconds;
typedef duration<long long              > seconds;
typedef duration<     long, ratio<  60> > minutes;
typedef duration<     long, ratio<3600> > hours;
是一个相当可移植的解决方案。但是对于libc++的
chrono
来说,这是不正确的。除了编写类似于
的自己的逻辑之外,没有其他可移植的方法。即,定义两个附加的
foo
定义,分别采用
long
unsigned long

或者另一个例子:

  foo(int8_t);
  foo(int16_t);
  foo(int32_t);
  foo(int64_t);
在这种情况下,调用
foo(duration.count())
是不明确的

那么使用
long-long
的意义是什么呢?它不大于
long
,但是它的秩大于
long
,所以不能隐式强制转换

这是
libc++
开发人员的疏忽吗


我之所以提出这个问题,是因为mongodb的驱动程序无法在x64 FreeBSD安装上编译。原因看起来很愚蠢。例如,gcc
std::chrono::duration
的定义中使用了
int64_t
,因此它按照预期进行编译。

标准只要求
seconds
duration
的类型定义,其比率为1,“有符号整数类型至少为35位”。所以libc++的实现是正确的

虽然使用
int64\t
在您的特定情况下会降低可移植性,但这只会让您走得更远。MSVC也使用
long-long
,而不是
int64\u t
。(尽管在这种情况下,它们是相同的类型。)该标准不保证持续时间
int64\t
,因此,即使多个实现使用它,依赖它也是不可移植的

这里的问题不是libc++的实现做了什么坏事。问题是C++的整数类型有点古怪,尽管
intNN\t
类型很方便,但它们并不能让您完全摆脱对底层类型的了解。特别是,试图用这些typedef为
foo
创建一个完整的重载集是错误的;正是因为您遇到的问题,您需要查找底层类型:重载集可能包含也可能不包含
long
,最终您将遇到该类型。它发生在libc++的
duration
typedefs上,而不是发生在其他情况下,这只是巧合


是的,这是一个糟糕的情况,但这个特定的问题只是更大问题的一个小症状。

标准不需要特定的整数类型来表示持续时间。它确实要求该类型可用作
rep
成员类型,因此您可以使用(例如,
std::chrono::duration::seconds::rep
作为适合以秒为单位存储值的类型。

我可以就这个问题发表一些权威性的意见,因为我是编写此代码的人。尽管其他两个答案都很好,我已经把它们投了更高的票

是的,我确实考虑过这些类型,并考虑用
int\u t*
typedef
s来定义它们

对于那些必须超过32位的重复,我选择了
long-long
,其余的则选择
long
。后者是在知道将目标从i386更改为x86_64时,
long
将从32位更改为64位的情况下完成的

如果我改为使用
int\u t*
typedef
s,很可能其他人也会抱怨这种设计中的歧义问题(比如
foo(int)
foo(long-long)
)。很难取悦所有人

我注意到,在mongodb标题mongo/src/mongo/util/time\u support.h中,它说:

using Microseconds = stdx::chrono::microseconds;
using Milliseconds = stdx::chrono::milliseconds;
using Seconds = stdx::chrono::seconds;
using Minutes = stdx::chrono::minutes;
using Hours = stdx::chrono::hours;
这很容易看起来像:

using Microseconds = stdx::chrono::duration<std::int64_t, stdx::chrono::microseconds::period>;
using Milliseconds = stdx::chrono::duration<std::int64_t, stdx::chrono::milliseconds::period>;
using Seconds = stdx::chrono::duration<std::int64_t, stdx::chrono::seconds::period>;
using Minutes = stdx::chrono::duration<std::int64_t, stdx::chrono::minutes::period>;
using Hours = stdx::chrono::duration<std::int64_t, stdx::chrono::hours::period>;
使用微秒=stdx::chrono::duration;
使用毫秒=stdx::chrono::duration;
使用秒=stdx::chrono::duration;
使用分钟=stdx::chrono::duration;
使用小时=stdx::chrono::duration;

也就是说,
库使客户可以非常轻松地创建自定义单元。听起来这可能是一个很好的解决方案,适用于mongodb

有64位平台,其中
long
为32位。检查LP64和LLP64平台之间的差异。请注意,这甚至是特定于编译器的,不仅针对平台,尽管通常存在某些约定。@UlrichEckhardt当然有,但这有什么用呢?库定义了
,所以为什么不将它用于上述库的另一部分的可移植性呢?我的观点是,你的前导句是错误的,而且,如果我理解你的问题,它是完全无关的!这不是归结为一个问题吗“为什么在一个平台上用
uint64_t
定义
duration
,在另一个平台上用
long
定义?”顺便问一下:你有关于mongodb构建问题的链接吗?@UlrichEckhardt问题将很快报告。真正的问题是为什么libc++的开发人员让库用户的生活变得更艰难。这里的问题到底是什么?在整数类型系统的问题上完全同意你的观点。多亏了
C
它完全搞定了。另一方面,您会期望这种渐进式库的开发人员有更多的意识:(我的论点是:我坚信,在C++11委员会中,通过采用
,在不同平台上解决了某些整数类型的不同大小的可移植性问题,迈出了一小步。很少看到库本身的实现不使用引入的类型,原因相同:可移植性。
using Microseconds = stdx::chrono::duration<std::int64_t, stdx::chrono::microseconds::period>;
using Milliseconds = stdx::chrono::duration<std::int64_t, stdx::chrono::milliseconds::period>;
using Seconds = stdx::chrono::duration<std::int64_t, stdx::chrono::seconds::period>;
using Minutes = stdx::chrono::duration<std::int64_t, stdx::chrono::minutes::period>;
using Hours = stdx::chrono::duration<std::int64_t, stdx::chrono::hours::period>;