fork download
  1. #include <type_traits>
  2. #include <utility>
  3.  
  4. #include <iostream>
  5.  
  6. using namespace std;
  7.  
  8. template <typename T>
  9. class Base
  10. {
  11. protected:
  12. template <typename U>
  13. Base(U&& callable)
  14. {
  15. cout << "called" << endl;
  16. static_assert(
  17. std::is_same<
  18. typename std::remove_reference<decltype(callable())>::type, T
  19. >::value,
  20. "Expression does not evaluate to correct type!");
  21. }
  22.  
  23. public:
  24. virtual ~Base(void) =default; // Causes error
  25.  
  26. virtual operator T(void) =0;
  27.  
  28. Base(Base&&)
  29. {
  30.  
  31. cout << "move called" << endl;
  32. }
  33. };
  34.  
  35. template <typename T, typename U>
  36. class Derived : public Base<T>
  37. {
  38. public:
  39. Derived(U&& callable) : Base<T>{std::forward<U>(callable)} {}
  40.  
  41. operator T(void) override final
  42. {
  43. return {};
  44. }
  45. };
  46.  
  47. void TakesWrappedInt(Base<int>&&) {}
  48.  
  49. template <typename U>
  50. auto MakeLazyInt(U&& callable)
  51. {
  52. return Derived<
  53. typename std::remove_reference<decltype(callable())>::type, U>{
  54. std::forward<U>(callable)};
  55. }
  56.  
  57. int main()
  58. {
  59. TakesWrappedInt(MakeLazyInt([&](){return 3;}));
  60. }
Success #stdin #stdout 0s 3412KB
stdin
Standard input is empty
stdout
called