VC++ 11 - std::condition_variable_any 与标准不兼容?
VC++ 11 - std::condition_variable_any not compatible with standard?
最近,我 运行 研究了 Microsoft Visual Studio 2012(配备 Visual C++ 11)上的 st运行ge 编译问题。
我移植了大型代码库,主要是在 Linux 上开发的,考虑到了 C++ 11 的广泛使用。尽管有一些细微的变化,但一切都运行良好。除了一件事:我收到关于 std::condition_variable::wait_for 结果类型的 st运行ge 错误。它的内容在这里无关紧要,因为我检查了这个并且...
参考页面(上面链接)说:
template< class Lock, class Rep, class Period >
std::cv_status wait_for(Lock&, const std::chrono::duration<Rep, Period>&)
并且:
template< class Lock, class Rep, class Period, class Predicate >
bool wait_for(Lock&, const std::chrono::duration<Rep, Period>&, Predicate)
我在某些地方用过std::cv_status
,所以我可以说,我依赖它的存在。但是,在 MSVC11 上,<conditional_variable>
包含:
template<class _Lock, class _Rep, class _Period>
bool wait_for(_Lock& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time)
并且:
template<class _Lock, class _Rep, class _Period, class _Predicate>
bool wait_for(_Lock& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time, _Predicate _Pred)
请注意第一种情况下的不同结果类型。我是这样的:
Errr... what?
我立即在 Linux (g++ 4.8
) 上检查了这个,这两个方法确实定义正确。
这是怎么回事? MS 发布了与标准不兼容的实现?
奇怪的是,我进一步调查 <condition_variable>
我发现了这个:
namespace cv_status { // names for wait returns
enum cv_status {
timeout,
no_timeout
};
} // namespace cv_status
但它是:
- 未使用
- 无效(*)
这是一些众所周知的错误吗?或者也许标准允许实现这样做?
(*) 标准定义了 enum class cv_status
,而不是 enum class cv_status::cv_status
.
还有一件事:wait_for
内部调用 wait_until
,看起来像这样:
bool _Res;
_Mtx_lock(&_Mtx);
_Xtrnl.unlock();
_Res = _Cnd_timedwaitX(&_Cnd, &_Mtx, _Abs_time) != _Thrd_timedout;
_Mtx_unlock(&_Mtx);
_Xtrnl.lock();
return (_Res);
所以,结果解释为:
true
-> std::cv_status::no_timeout
false
-> std::cv_status::timeout
如果有要求,no_timeout
必须定义为 1
,timeout
必须定义为 0
就可以了,但我没有看到类似的东西这个。实际上,在 Linux 上,有:
enum class cv_status { no_timeout, timeout };
因此这些枚举器将以不同于 Windows 的方式转换为布尔值。
尽管有Visual C++ 11.0的版本号,Visual Studio2012不支持C++11也没有声称支持。甚至下一个版本 (Visual Studio 2013) 也没有:有一个 CTP 可以添加重要的 C++11 功能,但即便如此,支持也不完整。 Visual Studio 2015 预计主要是 C++11 功能完整、语言明智,但我不确定标准库实现是否也是如此。
在标准化 C++11 的同时,有一点将此函数指定为 return bool
。正是在这一点上,微软将它添加到他们的实现中,并且由于无论如何都不支持 C++11,所以当标准更新时它根本就没有更新。
评论指出这个特定的函数在 VS2013 中已经改变了,但是,如果你想要一个 C++11 实现,那么 VS2012 和 VS2013 都不行。
最近,我 运行 研究了 Microsoft Visual Studio 2012(配备 Visual C++ 11)上的 st运行ge 编译问题。
我移植了大型代码库,主要是在 Linux 上开发的,考虑到了 C++ 11 的广泛使用。尽管有一些细微的变化,但一切都运行良好。除了一件事:我收到关于 std::condition_variable::wait_for 结果类型的 st运行ge 错误。它的内容在这里无关紧要,因为我检查了这个并且...
参考页面(上面链接)说:
template< class Lock, class Rep, class Period >
std::cv_status wait_for(Lock&, const std::chrono::duration<Rep, Period>&)
并且:
template< class Lock, class Rep, class Period, class Predicate >
bool wait_for(Lock&, const std::chrono::duration<Rep, Period>&, Predicate)
我在某些地方用过std::cv_status
,所以我可以说,我依赖它的存在。但是,在 MSVC11 上,<conditional_variable>
包含:
template<class _Lock, class _Rep, class _Period>
bool wait_for(_Lock& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time)
并且:
template<class _Lock, class _Rep, class _Period, class _Predicate>
bool wait_for(_Lock& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time, _Predicate _Pred)
请注意第一种情况下的不同结果类型。我是这样的:
Errr... what?
我立即在 Linux (g++ 4.8
) 上检查了这个,这两个方法确实定义正确。
这是怎么回事? MS 发布了与标准不兼容的实现?
奇怪的是,我进一步调查 <condition_variable>
我发现了这个:
namespace cv_status { // names for wait returns
enum cv_status {
timeout,
no_timeout
};
} // namespace cv_status
但它是:
- 未使用
- 无效(*)
这是一些众所周知的错误吗?或者也许标准允许实现这样做?
(*) 标准定义了 enum class cv_status
,而不是 enum class cv_status::cv_status
.
还有一件事:wait_for
内部调用 wait_until
,看起来像这样:
bool _Res;
_Mtx_lock(&_Mtx);
_Xtrnl.unlock();
_Res = _Cnd_timedwaitX(&_Cnd, &_Mtx, _Abs_time) != _Thrd_timedout;
_Mtx_unlock(&_Mtx);
_Xtrnl.lock();
return (_Res);
所以,结果解释为:
true
->std::cv_status::no_timeout
false
->std::cv_status::timeout
如果有要求,no_timeout
必须定义为 1
,timeout
必须定义为 0
就可以了,但我没有看到类似的东西这个。实际上,在 Linux 上,有:
enum class cv_status { no_timeout, timeout };
因此这些枚举器将以不同于 Windows 的方式转换为布尔值。
尽管有Visual C++ 11.0的版本号,Visual Studio2012不支持C++11也没有声称支持。甚至下一个版本 (Visual Studio 2013) 也没有:有一个 CTP 可以添加重要的 C++11 功能,但即便如此,支持也不完整。 Visual Studio 2015 预计主要是 C++11 功能完整、语言明智,但我不确定标准库实现是否也是如此。
在标准化 C++11 的同时,有一点将此函数指定为 return bool
。正是在这一点上,微软将它添加到他们的实现中,并且由于无论如何都不支持 C++11,所以当标准更新时它根本就没有更新。
评论指出这个特定的函数在 VS2013 中已经改变了,但是,如果你想要一个 C++11 实现,那么 VS2012 和 VS2013 都不行。