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);

所以,结果解释为:

如果有要求,no_timeout 必须定义为 1timeout 必须定义为 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 都不行。