在chrono代码中出现了奇怪的错误 "C2440: '<function-style-cast>' : cannot convert from '_CR' to 'std::chrono::milliseconds'"。

5

我遇到了一个奇怪的错误。

C2440: '' : 无法从'_CR'转换为'std::chrono::milliseconds'

这个错误基本上是在 Howard Hinnant另一个问题中的代码中发现的。

这段代码是否应该在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(); }

}

编辑

根据Howard Hinnant的说明,头文件、实现文件和调用文件中都需要包含#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))));
}

具体来说是在<chrono>的第573行,如上所述

 [...]
 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调用中,有六个编译器错误。如果我将方便方法注释掉,代码就可以编译和运行了。

嗯,我想知道有什么好的解决方法(或修复方法)..?

2个回答

7

确实,这就是原因。我看到你也将此提交给了MS Connect,谢谢你! - Veksi
这里似乎还有 Microsoft Visual Studio Premium 2012 Version 11.0.61219.00 Update 5 - Software Craftsman
什么是“period”? - Head Wizard Locke
我因为另一个原因(无法将“int”转换为“milliseconds”)而来到这里,但通过使用x = std :: chrono :: milliseconds {0}而不是x = 0;,我克服了这个问题。 - Head Wizard Locke

0

如果我添加以下内容,您的代码就可以编译通过:

#include <chrono>

对此我无能为力。我没有访问Visual Studio 2012 RC的权限,因此无法调查此错误的原因,甚至无法确定它发生的位置。


嗨!我稍微编辑了一下问题,加入了更多的细节。我已经在所有文件中包含了<chrono>。 - Veksi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接