Странная ошибка в хронокоде C2440: «‹function-style-cast›»: невозможно преобразовать из «_CR» в «std::chrono::milliseconds»

Я наткнулся на странную ошибку

C2440: '': невозможно преобразовать из '_CR' в 'std::chrono::milliseconds'

в основном это код Говарда Хиннанта в еще один вопрос.

Должно ли это компилироваться в Visual Studio 2012 RC? Что может быть причиной этой проблемы? Как насчет исправления или обходного пути? Моя цель состоит в том, чтобы просто создать простой таймер (ничего серьезного), поэтому, если существует что-то подобное, точка будет принята, а также другие подсказки реализации.

Рассматриваемый код выглядит следующим образом. Использование:

  timers::stopwatch w;
  w.start();
  std::cout << to_milliseconds(w.elapsed()) << std::endl;

И заголовочный файл (реализация опущена для краткости)

namespace timers
{
    class stopwatch
    {
        public:
            typedef std::chrono::high_resolution_clock clock;
            typedef clock::time_point time_point;
            typedef clock::period period;
            typedef std::chrono::duration<float, period> duration;

            stopwatch();
            ~stopwatch();

            void start();
            void stop();
            void restart();
            void reset();

            duration elapsed() const;
       private:
            clock timer_;
            time_point start_point_;
            time_point end_point_;
            bool is_running_;

            void start_measuring();
            void stop_measuring();
     };
}

//Some convenience stuff...
namespace
{       
    long long to_milliseconds(timers::stopwatch::duration const& duration) { return   std::chrono::duration_cast<std::chrono::milliseconds>(duration).count(); }
    long long to_nanoseconds(timers::stopwatch::duration const& duration) { return std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count(); }
    long long to_seconds(timers::stopwatch::duration const& duration) { return std::chrono::duration_cast<std::chrono::seconds>(duration).count(); }

}

Редактировать

Согласно примечанию Говарда Хиннанта, в заголовке, файле реализации и вызывающем файле есть #include <chrono>. Ошибка указывает на заголовок MS <chrono>, и ошибка возникает в этом коде.

// duration_cast
template<class _To,
    class _Rep,
    class _Period> inline
    typename enable_if<_Is_duration<_To>::value,
        _To>::type
        duration_cast(const duration<_Rep, _Period>& _Dur)
        {    // convert duration to another duration
            typedef typename ratio_divide<_Period, typename _To::period>::type _CF;
            typedef typename common_type<
            typename common_type<typename _To::rep, _Rep>::type,
                intmax_t>::type _CR;
                if (_CF::num == 1 && _CF::den == 1)
                    return (_To(static_cast<typename _To::rep>(_Dur.count())));
                else if (_CF::num != 1 && _CF::den == 1)
                    return (_To(static_cast<typename _To::rep>(static_cast<_CR>(_Dur.count())) * static_cast<_CR>(_CF::num)));
                else if (_CF::num == 1 && _CF::den != 1)
            return (_To(static_cast<typename _To::rep>(static_cast<_CR>(_Dur.count()) / static_cast<_CR>(_CF::den))));
                else
                    return (_To(static_cast<typename _To::rep>(xtatic_cast<_CR> _Dur.count()) * static_cast<_CR>(_CF::num) / static_cast<_CR>(_CF::den))));
}

и конкретно в строке 573 из <chrono>, которая на вышеупомянутом

 [...]
 else if (_CF::num != 1 && _CF::den == 1)
     return (_To(static_cast<typename _To::rep>(static_cast<_CR>(_Dur.count())) * static_cast<_CR>(_CF::num)));

Я не могу понять цель всего этого кода (пока, по крайней мере), чтобы иметь определенное мнение, если это что-то где-то в моем коде или в заголовке VC++ <chrono>. Я узнаю некоторые имена из TC1/SC22/ WG21 n2661. В любом случае, я вернусь к компьютеру позже и посмотрю, влияет ли изоляция stopwatch в отдельный проект на возникновение этой ошибки.

Редактировать 2

Я поместил код в пустой проект, и проблема все еще существует. В качестве дополнительного примечания: для трех вызовов to_*seconds возникает шесть ошибок компилятора. Если я помещу удобные методы в комментарии, код скомпилируется и запустится.

Хм, интересно, что было бы хорошим обходным путем (или исправить)?..?


person Veksi    schedule 01.09.2012    source источник


Ответы (2)


Я думаю, что ошибка времени компиляции связана с этой ошибкой в ​​Visual Studio 2012 RC:

https://connect.microsoft.com/VisualStudio/feedback/details/752794/std-chrono-duration-cast-lacks-double-support

Чтобы обойти это, используйте длительность, основанную на целочисленном типе вместо плавающей запятой:

#include <cstdint>
//...
typedef std::chrono::duration<std::uint64_t, period> duration;
person Thomas Petit    schedule 02.09.2012
comment
Собственно, это и было причиной. Я вижу, вы также отправили это в MS Connect, спасибо и за это! - person Veksi; 02.09.2012
comment
Microsoft Visual Studio Premium 2012 Version 11.0.61219.00 Update 5 здесь. Вроде еще есть... - person Vivit; 12.12.2016

Ваш код скомпилируется для меня, если я добавлю:

#include <chrono>

к этому. У меня нет доступа к Visual Studio 2012 RC, поэтому я не могу выяснить причину этой ошибки или даже определить, где она возникает.

person Howard Hinnant    schedule 02.09.2012
comment
Привет! Я немного отредактировал вопрос, чтобы включить больше деталей. У меня ‹хроно› включен во все файлы. - person Veksi; 02.09.2012