最近,我在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
必须定义为1
,timeout
定义为0
,那就没问题,但我没有看到这样的内容。实际上,在Linux上,有:
enum class cv_status { no_timeout, timeout };
因此,这些枚举器将以与Windows不同的方式转换为bool。
答案 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都不会这样做。