2

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...

4
  • 2
    "Here's full code sample" where are #includes? Commented Nov 14, 2018 at 7:51
  • @Swordfish They surely wouldn't help with understanding the question. Commented Nov 14, 2018 at 7:53
  • @Swordfish Sorry..I've updated. Commented Nov 14, 2018 at 7:53
  • @Zereges It would help with me being too lacy to add them. Commented Nov 14, 2018 at 7:54

1 Answer 1

2

::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.

Sign up to request clarification or add additional context in comments.

2 Comments

I understand that. But what do I need to do to use a syntax like std::this_thread::sleep_for(timeout)? How can I "tell" to the compiler that I wish to convert struct timeout to `std::chrono::duration<rep,period>'?
@JacintoResende You can cast it explicitly std::this_thread::sleep_for(static_cast<timeout_tp::Duration_>(timeout)) or specify template parameters explicitly std::this_thread::sleep_for<timeout_tp::rep_, timeout_tp::period_>(timeout). Or you can just write your own sleep_for function that would take timeout_tp for convenience.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.