VC++ 11 - std::condition_variable_any не совместим со стандартом?
Недавно я столкнулся со странными проблемами компиляции в 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
->std::cv_status::no_timeout
false
->std::cv_status::timeout
Если было требование, то no_timeout
должен быть определен как 1
а также timeout
как 0
было бы хорошо, но я не вижу ничего подобного. На самом деле в Linux было:
enum class cv_status { no_timeout, timeout };
Таким образом, эти перечислители будут преобразованы в bool иначе, чем в Windows.
1 ответ
Несмотря на номер версии Visual C++ 11.0, Visual Studio 2012 не поддерживает C++ 11 и не претендует на его поддержку. Даже в следующей версии (Visual Studio 2013) нет: есть CTP для добавления значительных функций C++ 11, но даже тогда поддержка не завершена. Ожидается, что Visual Studio 2015 будет в основном C++ 11 с полной функциональностью и языком, но я не уверен, будет ли реализация стандартной библиотеки такой же.
В то время как C++ 11 был стандартизирован, был момент, когда эта функция была указана для возврата bool
, Именно в этот момент Microsoft добавила его в свою реализацию, и, поскольку C++ 11 все равно не поддерживался, он просто не обновлялся, когда обновлялся стандарт.
В комментариях указывается, что эта конкретная функция уже была изменена в VS2013, но, тем не менее, если вы хотите реализацию C++ 11, то ни VS2012, ни VS2013 не подойдут.