5

I stumbled upon a strange error

C2440: '' : cannot convert from '_CR' to 'std::chrono::milliseconds'

in what amounts basically to Howard Hinnant's code in another question.

Should this compile on Visual Studio 2012 RC? What would be the reason for this problem? How about a fix or a workaround? My aim is just to create a simple timer (nothing too serious), so if there exists something to that effect, point will be taken -- as well as other implementation cues.

The code in question is as follows. Usage:

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

And the header file is (implementation ommitted for breverity)

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(); } 

}

Edit

As as per Howard Hinnant's note, there's #include <chrono> in the header, the implementation file and the calling file. The error points to MS <chrono> header and the error is triggered in this code

// 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)))); } 

and specifically on line 573 of <chrono>, which on the aforementioned is

 [...] 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))); 

I can't really follow the purpose of all of that code (yet, at least) to have a definite opinition if it's something in my code somewhere or in the VC++ <chrono> header. I recognise some of naming from TC1/SC22/WG21 n2661. In any event, I'll get back to computer later and see if isolating the stopwatchto a project of its own affects the occurence of this error.

Edit 2

I put the code to an empty project and the problem is still there. As an added note, for the three to_*seconds calls there are six compiler errors. If I put the convenience methods to comments, the code compiles and runs.

Hmm, I wonder what would be a good work-around (or fix)..?

2 Answers 2

7

I think that the compile-time error is due to this bug in Visual Studio 2012 RC :

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

To workaround it, use a duration based on integral type instead of floating point :

#include <cstdint> //... typedef std::chrono::duration<std::uint64_t, period> duration; 
Sign up to request clarification or add additional context in comments.

4 Comments

Indeed, this was the reason. I see you also submitted this to MS Connect, thanks for that too!
Microsoft Visual Studio Premium 2012 Version 11.0.61219.00 Update 5 here. Seems still to be there...
What is "period"
I ended up here for another reason (could not cast "int" to "milliseconds") but overcame this by using x = std::chrono::milliseconds{0} instead of x = 0;
0

Your code compiles for me if I add:

#include <chrono> 

to it. I do not have access to Visual Studio 2012 RC, so I can not investigate the cause of this error, or even be sure of where it is occurring.

1 Comment

Hi! I edited the question a bit to include more details. I have <chrono> included in all files.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.