fork download
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. struct BrokenDataWrapperByMoveOrCopy;
  5.  
  6. struct Data {
  7. Data() { std::cout << " constructor\n";}
  8. Data(const Data& data) { std::cout << " copy constructor\n";}
  9. Data(Data&& data) { std::cout << " move constructor\n";}
  10. explicit Data(int i) { std::cout << " explicitly constructed from int\n";}
  11. private:
  12. explicit Data(void* p) { std::cout << " only my friend knows how to construct me from a void*\n"; }
  13. friend BrokenDataWrapperByMoveOrCopy;
  14. };
  15.  
  16. struct DataWrapperByMoveOrCopy {
  17. Data data_;
  18. template<typename T,
  19. typename = typename std::enable_if<
  20. std::is_same<typename std::decay<T>::type, Data>::value
  21. >::type
  22. >
  23. DataWrapperByMoveOrCopy(T&& data) : data_(std::forward<T>(data)) { }
  24. };
  25.  
  26. struct BrokenDataWrapperByMoveOrCopy {
  27. Data data_;
  28. template<typename T>
  29. BrokenDataWrapperByMoveOrCopy(T&& data) : data_(std::forward<T>(data)) { }
  30. };
  31.  
  32. int main() {
  33.  
  34. std::cout << "1. DataWrapperByMoveOrCopy:\n";
  35. Data d1;
  36. DataWrapperByMoveOrCopy a1(std::move(d1));
  37.  
  38. std::cout << "2. BrokenDataWrapperByMoveOrCopy:\n";
  39. int d2; //oops is an int rather than a Data
  40. BrokenDataWrapperByMoveOrCopy a2(std::move(d2)); //this compiles, ouch
  41.  
  42. std::cout << "3. DataWrapperByMoveOrCopy:\n";
  43. int d3; //oops is an int rather than a Data
  44. //DataWrapperByMoveOrCopy a3(std::move(d3)); //this failes as its supposed to
  45.  
  46. std::cout << "4. BrokenDataWrapperByMoveOrCopy:\n";
  47. int* p = nullptr;
  48. BrokenDataWrapperByMoveOrCopy a4(p); //this compiles, this is terrible
  49.  
  50. }
Success #stdin #stdout 0s 3340KB
stdin
Standard input is empty
stdout
1. DataWrapperByMoveOrCopy:
  constructor
  move constructor
2. BrokenDataWrapperByMoveOrCopy:
 explicitly constructed from int
3. DataWrapperByMoveOrCopy:
4. BrokenDataWrapperByMoveOrCopy:
 only my friend knows how to construct me from a void*