fork download
  1. #include <algorithm>
  2. #include <functional>
  3. #include <iostream>
  4. #include <vector>
  5.  
  6. template<typename InIt, typename OutIt, typename Fun>
  7. class is_valid_transform
  8. {
  9. private:
  10. class YES
  11. {
  12. char dummy[2]; // size > 1
  13. };
  14.  
  15. typedef char NO; // size == 1
  16.  
  17. // std::transform has return type OutIt which will only convert to
  18. // InIt if OutIt does not have stronger const-ness properties.
  19. static YES test(InIt);
  20.  
  21. // SFINAE fallback: ... has lowest priority
  22. static NO test(...);
  23.  
  24. public:
  25. // equivalent to sizeof(test(OutIt()) != sizeof(NO)
  26. static const bool value = sizeof(test(std::transform(InIt(), InIt(), OutIt(), Fun()))) != sizeof(NO);
  27. };
  28.  
  29. int main()
  30. {
  31. typedef std::vector<int>::iterator iter1;
  32. typedef std::vector<int>::const_iterator iter2;
  33. typedef std::vector<std::string>::iterator iter3;
  34. typedef std::negate<int> func;
  35.  
  36. auto strinf = [](int)->std::string { return "hello"; };
  37.  
  38. std::cout << "valid transform compiles: " << is_valid_transform<iter1,iter1,func>::value << std::endl;
  39. std::cout << "invalid transform compiles: " << is_valid_transform<iter1,iter2,func>::value << std::endl;
  40. std::cout << "valid transform compiles: " << is_valid_transform<iter2,iter1,func>::value << std::endl;
  41. std::cout << "invalid transform compiles: " << is_valid_transform<iter1,iter3,decltype(&strinf)>::value << std::endl;
  42. std::transform(iter1(), iter1(), iter3(), strinf);
  43.  
  44. return 0;
  45. }
Success #stdin #stdout 0s 2828KB
stdin
Standard input is empty
stdout
valid transform compiles: 1
invalid transform compiles: 0
valid transform compiles: 1
invalid transform compiles: 0