fork download
  1. #include <iostream>
  2. #include <typeinfo>
  3. #include <memory>
  4.  
  5. struct nil { };
  6.  
  7. //スマートポインタを生ポインタと同様に扱うための変換
  8. //int -> nil*, int* -> int*, smart_ptr<int> -> int*
  9. template <typename T>
  10. class dereferencable {
  11. static T getT();
  12. template <typename U>
  13. static std::true_type test1(U&& u, decltype(*u, 0) = 0); //本来はtest1だけでOKのはず
  14. template <typename U>
  15. static std::true_type test2(U&& u, typename std::enable_if<std::is_same< //workaround for VC2012
  16. typename std::remove_cv<typename std::remove_reference<decltype(&*u)>::type>::type,
  17. typename std::remove_cv<typename std::remove_reference<decltype(&u)>::type>::type
  18. >::value>::type* = 0 );
  19. static std::false_type test1(...);
  20. static std::false_type test2(...);
  21. typedef decltype(test1(getT())) T1;
  22. typedef decltype(test2(getT())) T2;
  23. typedef typename std::conditional<T1::value && !T2::value, T, nil*>::type psp_type;
  24. static psp_type getPSP();
  25. public:
  26. static const bool value = (T1::value && !T2::value); //int -> false, int* -> true, s_ptr<int> -> true
  27. typedef decltype(&*getPSP()) p_type; //int -> nil*, int* -> int*, s_ptr<int> -> int*
  28. };
  29.  
  30. int main()
  31. {
  32. int v=9;
  33. int* p = &v;
  34. std::unique_ptr<int> sp(new int(14312421));
  35.  
  36. std::cout << dereferencable<decltype(v)>::value << std::endl;
  37. std::cout << dereferencable<decltype(p)>::value << std::endl;
  38. std::cout << dereferencable<decltype(sp)>::value << std::endl;
  39.  
  40. std::cout << typeid(nil*).name() << " : " <<
  41. typeid(dereferencable<decltype(v)>::p_type).name() << std::endl;
  42. std::cout << typeid(int*).name() << " : " <<
  43. typeid(dereferencable<decltype(p)>::p_type).name() << std::endl;
  44. std::cout << typeid(int*).name() << " : " <<
  45. typeid(dereferencable<decltype(sp)>::p_type).name() << std::endl;
  46.  
  47.  
  48. return 0;
  49. }
Success #stdin #stdout 0s 3428KB
stdin
Standard input is empty
stdout
0
1
1
P3nil : P3nil
Pi : Pi
Pi : Pi