2
votes

I'm trying to create a struct timeout. I would like to use it directly.e.g. std::this_thread::sleep_for(timeout). However my user defined conversion fails when converting from struct timeoutto std::chrono::duration<rep,period> for some reason I can't understand. Here's full code sample:

#include <chrono>
#include <thread>
template <typename Duration = std::chrono::milliseconds>
struct timeout_tp
{
   using Duration_   = Duration;
   using rep_        = typename Duration_::rep;
   using period_     = typename Duration_::period;

   timeout_tp(const rep_ &timeout) : timeout{timeout} {}    
   operator Duration_() const {return timeout;}
   Duration_ operator()() const {return timeout;}
   //...
   private:   
   Duration_ timeout;
};

int main()
{
   timeout_tp<std::chrono::seconds> timeout{1};
   std::chrono::seconds x = timeout; //OK: struct timeout conversion to std::chrono::seconds.
   std::this_thread::sleep_for(x);
   //std::this_thread::sleep_for(timeout); : FAILS!!! Can't understand why... 
   std::this_thread::sleep_for(timeout()); //OK : struct timeout operator() returns std::chrono::seconds.
   return 0;
}

What am I doing wrong?

What do I need to do in order to use the desired syntax?

Error messages issued by the compiler:

main.cpp:38:39: error: no matching function for call to ‘sleep_for(timeout_tp<>&)’ std::this_thread::sleep_for(timeout); //FAILS!!! Can't understand why... ^

In file included from main.cpp:16:0: /usr/include/c++/7/thread:361:7: note: candidate: template void std::this_thread::sleep_for(const std::chrono::duration<_Rep1, _Period1>&) sleep_for(const chrono::duration<_Rep, _Period>& __rtime) ^~~~~~~~~ /usr/include/c++/7/thread:361:7: note: template argument deduction/substitution failed:

main.cpp:38:39: note: ‘timeout_tp<>’ is not derived from ‘const std::chrono::duration<_Rep1, _Period1>’ std::this_thread::sleep_for(timeout); //FAILS!!! Can't understand why...

1
"Here's full code sample" where are #includes?Swordfish
@Swordfish They surely wouldn't help with understanding the question.Zereges
@Swordfish Sorry..I've updated.Jacinto Resende
@Zereges It would help with me being too lacy to add them.Swordfish

1 Answers

2
votes

::std::this_thread::sleep_for is a template declared as

template< class Rep, class Period >
void sleep_for( const std::chrono::duration<Rep, Period> & sleep_duration );

When you pass an instance of timeout_tp template parameters Rep and Period can not be deduced and user-defined conversion operator timeout_tp to std::chrono::milliseconds is not even taken into consideration.