VC ++ 11 - std :: condition_variable_any与标准不兼容吗?

时间:2015-05-17 21:24:39

标签: c++ c++11 visual-studio-2012 condition-variable

最近,我在Microsoft Visual Studio 2012(配备Visual C ++ 11)上遇到了奇怪的编译问题。

我移植了大量的代码库,主要是在Linux上开发的,考虑到了大量的C ++ 11用法。尽管发生了一些细微的变化,但一切都运转良除了一件事:我对std::condition_variable::wait_for的结果类型有一个奇怪的错误。它的内容在这里无关紧要,因为我检查了这个......

参考页面(上面链接)说:

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)

注意第一种情况下的不同结果类型。我当时想:

  

呃...什么?

我立即在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 - &gt; std::cv_status::no_timeout
  • false - &gt; std::cv_status::timeout

如果有要求,no_timeout必须定义为1timeout定义为0,那就没问题,但我没有看到这样的内容。实际上,在Linux上,有:

enum class cv_status { no_timeout, timeout };

因此,这些枚举器将以与Windows不同的方式转换为bool。

1 个答案:

答案 0 :(得分:3)

尽管Visual C ++ 11.0的版本号,但Visual Studio 2012不支持C ++ 11,并且不声称支持它。甚至下一个版本(Visual Studio 2013)都没有:有一个CTP可以添加重要的C ++ 11功能,但即使这样,支持也是不完整的。预计Visual Studio 2015主要是C ++ 11功能完备的,语言方面的,但我不确定标准库的实现是否也会如此。

虽然C ++ 11正在标准化,但有一点指定此函数返回bool。正是在这一点上,微软将它添加到它们的实现中,并且由于不支持C ++ 11,所以当标准更新时它根本就没有更新。

评论指出这个特定功能已经在VS2013中进行了更改,但是,如果你想要一个C ++ 11实现,那么VS2012和VS2013都不会这样做。