fork(3) download
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4. template <typename T>
  5. using Return = typename std::conditional<std::is_rvalue_reference<T>::value, typename std::remove_reference<T>::type, T>::type;
  6.  
  7. template <typename T>
  8. using CRef = typename std::remove_reference<T>::type const&;
  9.  
  10. template<typename Str>
  11. Return<Str> StringReplace(Str&& str, CRef<Str> from, CRef<Str> to)
  12. {
  13. std::cout << __PRETTY_FUNCTION__ << std::endl;
  14. if (std::is_same<std::string&&, decltype(str)>::value)
  15. std::cout << "rvalue-ref\n\n";
  16. else if (std::is_same<std::string&, decltype(str)>::value)
  17. std::cout << "lvalue-ref\n\n";
  18. return std::forward<Str>(str);
  19. }
  20.  
  21. int main() {
  22. std::string s1;
  23.  
  24. StringReplace(s1, "", "");
  25.  
  26. // Forwarding reference will deduce Str to std::string& when passing an lvalue
  27. StringReplace<std::string&>(s1, "", "");
  28.  
  29. StringReplace(std::move(s1), "", "");
  30.  
  31. StringReplace<std::string>(std::move(s1), "", "");
  32.  
  33. StringReplace<std::string>("", "", "");
  34.  
  35. const std::string& test = s1;
  36. StringReplace(test, "", "");
  37. }
Success #stdin #stdout 0s 4396KB
stdin
Standard input is empty
stdout
Return<Str> StringReplace(Str&&, CRef<Str>, CRef<Str>) [with Str = std::__cxx11::basic_string<char>&; Return<Str> = std::__cxx11::basic_string<char>&; CRef<Str> = const std::__cxx11::basic_string<char>&; typename std::remove_reference< <template-parameter-1-1> >::type = std::__cxx11::basic_string<char>]
lvalue-ref

Return<Str> StringReplace(Str&&, CRef<Str>, CRef<Str>) [with Str = std::__cxx11::basic_string<char>&; Return<Str> = std::__cxx11::basic_string<char>&; CRef<Str> = const std::__cxx11::basic_string<char>&; typename std::remove_reference< <template-parameter-1-1> >::type = std::__cxx11::basic_string<char>]
lvalue-ref

Return<Str> StringReplace(Str&&, CRef<Str>, CRef<Str>) [with Str = std::__cxx11::basic_string<char>; Return<Str> = std::__cxx11::basic_string<char>; CRef<Str> = const std::__cxx11::basic_string<char>&; typename std::remove_reference< <template-parameter-1-1> >::type = std::__cxx11::basic_string<char>]
rvalue-ref

Return<Str> StringReplace(Str&&, CRef<Str>, CRef<Str>) [with Str = std::__cxx11::basic_string<char>; Return<Str> = std::__cxx11::basic_string<char>; CRef<Str> = const std::__cxx11::basic_string<char>&; typename std::remove_reference< <template-parameter-1-1> >::type = std::__cxx11::basic_string<char>]
rvalue-ref

Return<Str> StringReplace(Str&&, CRef<Str>, CRef<Str>) [with Str = std::__cxx11::basic_string<char>; Return<Str> = std::__cxx11::basic_string<char>; CRef<Str> = const std::__cxx11::basic_string<char>&; typename std::remove_reference< <template-parameter-1-1> >::type = std::__cxx11::basic_string<char>]
rvalue-ref

Return<Str> StringReplace(Str&&, CRef<Str>, CRef<Str>) [with Str = const std::__cxx11::basic_string<char>&; Return<Str> = const std::__cxx11::basic_string<char>&; CRef<Str> = const std::__cxx11::basic_string<char>&; typename std::remove_reference< <template-parameter-1-1> >::type = const std::__cxx11::basic_string<char>]