#include <iostream>
#include <type_traits>
#include <string>
template<typename Str, typename = std::enable_if_t<!std::is_const<std::remove_reference_t<Str>>::value>>
Str StringReplace(Str&& str, const std::remove_reference_t<Str>& from, const std::remove_reference_t<Str>& to)
{
std::cout << "non-const" << std::endl;
std::cout << __PRETTY_FUNCTION__ << std::endl;
return std::forward<Str>(str);
}
template<typename Str, typename = std::enable_if_t<std::is_const<std::remove_reference_t<Str>>::value>>
std::decay_t<Str> StringReplace(Str&& str, const std::remove_reference_t<Str>& from, const std::remove_reference_t<Str>& to)
{
std::cout << "const" << std::endl;
std::cout << __PRETTY_FUNCTION__ << std::endl;
std::decay_t<Str> mutableStr{std::forward<Str>(str)};
StringReplace(mutableStr, from, to);
return mutableStr;
}
int main()
{
{
std::cout << "lvalue" << std::endl;
std::string v;
StringReplace(v, "", "");
}
{
std::cout << std::endl << "const lvalue" << std::endl;
const std::string v;
StringReplace(v, "", "");
}
{
std::cout << std::endl << "lvalue reference" << std::endl;
std::string v;
std::string& vref = v;
StringReplace(vref, "", "");
}
{
std::cout << std::endl << "const lvalue reference" << std::endl;
std::string v;
const std::string& vref = v;
StringReplace(vref, "", "");
}
{
std::cout << std::endl << "rvalue" << std::endl;
std::string v;
StringReplace(std::move(v), "", "");
}
{
std::cout << std::endl << "const rvalue" << std::endl;
const std::string v;
StringReplace(std::move(v), "", "");
}
{
std::cout << std::endl << "rvalue reference" << std::endl;
std::string&& v = std::string();
StringReplace(v, "", "");
}
{
std::cout << std::endl << "const rvalue reference" << std::endl;
const std::string&& v = std::string();
StringReplace(v, "", "");
}
{
std::cout << std::endl << "string literal" << std::endl;
StringReplace<std::string>("", "", "");
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDxzdHJpbmc+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBTdHIsIHR5cGVuYW1lID0gc3RkOjplbmFibGVfaWZfdDwhc3RkOjppc19jb25zdDxzdGQ6OnJlbW92ZV9yZWZlcmVuY2VfdDxTdHI+Pjo6dmFsdWU+PgpTdHIgU3RyaW5nUmVwbGFjZShTdHImJiBzdHIsIGNvbnN0IHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZV90PFN0cj4mIGZyb20sIGNvbnN0IHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZV90PFN0cj4mIHRvKQp7CglzdGQ6OmNvdXQgPDwgIm5vbi1jb25zdCIgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8IF9fUFJFVFRZX0ZVTkNUSU9OX18gPDwgc3RkOjplbmRsOwogICAgcmV0dXJuIHN0ZDo6Zm9yd2FyZDxTdHI+KHN0cik7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFN0ciwgdHlwZW5hbWUgPSBzdGQ6OmVuYWJsZV9pZl90PHN0ZDo6aXNfY29uc3Q8c3RkOjpyZW1vdmVfcmVmZXJlbmNlX3Q8U3RyPj46OnZhbHVlPj4Kc3RkOjpkZWNheV90PFN0cj4gU3RyaW5nUmVwbGFjZShTdHImJiBzdHIsIGNvbnN0IHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZV90PFN0cj4mIGZyb20sIGNvbnN0IHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZV90PFN0cj4mIHRvKQp7CglzdGQ6OmNvdXQgPDwgImNvbnN0IiA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgX19QUkVUVFlfRlVOQ1RJT05fXyA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6OmRlY2F5X3Q8U3RyPiBtdXRhYmxlU3Rye3N0ZDo6Zm9yd2FyZDxTdHI+KHN0cil9OwogICAgU3RyaW5nUmVwbGFjZShtdXRhYmxlU3RyLCBmcm9tLCB0byk7CiAgICByZXR1cm4gbXV0YWJsZVN0cjsKfQoKaW50IG1haW4oKQp7CiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8ICJsdmFsdWUiIDw8IHN0ZDo6ZW5kbDsKICAgICAgICBzdGQ6OnN0cmluZyB2OwogICAgICAgIFN0cmluZ1JlcGxhY2UodiwgIiIsICIiKTsKICAgIH0KCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbCA8PCAiY29uc3QgbHZhbHVlIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcgdjsKICAgICAgICBTdHJpbmdSZXBsYWNlKHYsICIiLCAiIik7CiAgICB9CiAgICAKICAgIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsIDw8ICJsdmFsdWUgcmVmZXJlbmNlIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3RkOjpzdHJpbmcgdjsKICAgICAgICBzdGQ6OnN0cmluZyYgdnJlZiA9IHY7CiAgICAgICAgU3RyaW5nUmVwbGFjZSh2cmVmLCAiIiwgIiIpOwogICAgfQoKICAgIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsIDw8ICJjb25zdCBsdmFsdWUgcmVmZXJlbmNlIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3RkOjpzdHJpbmcgdjsKICAgICAgICBjb25zdCBzdGQ6OnN0cmluZyYgdnJlZiA9IHY7CiAgICAgICAgU3RyaW5nUmVwbGFjZSh2cmVmLCAiIiwgIiIpOwogICAgfQogICAgCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbCA8PCAicnZhbHVlIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3RkOjpzdHJpbmcgdjsKICAgICAgICBTdHJpbmdSZXBsYWNlKHN0ZDo6bW92ZSh2KSwgIiIsICIiKTsKICAgIH0KCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbCA8PCAiY29uc3QgcnZhbHVlIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcgdjsKICAgICAgICBTdHJpbmdSZXBsYWNlKHN0ZDo6bW92ZSh2KSwgIiIsICIiKTsKICAgIH0KCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbCA8PCAicnZhbHVlIHJlZmVyZW5jZSIgPDwgc3RkOjplbmRsOwogICAgICAgIHN0ZDo6c3RyaW5nJiYgdiA9IHN0ZDo6c3RyaW5nKCk7CiAgICAgICAgU3RyaW5nUmVwbGFjZSh2LCAiIiwgIiIpOwogICAgfQoKICAgIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsIDw8ICJjb25zdCBydmFsdWUgcmVmZXJlbmNlIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcmJiB2ID0gc3RkOjpzdHJpbmcoKTsKICAgICAgICBTdHJpbmdSZXBsYWNlKHYsICIiLCAiIik7CiAgICB9CgogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCBzdGQ6OmVuZGwgPDwgInN0cmluZyBsaXRlcmFsIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgU3RyaW5nUmVwbGFjZTxzdGQ6OnN0cmluZz4oIiIsICIiLCAiIik7CiAgICB9CiAgICAKCXJldHVybiAwOwp9
lvalue
non-const
Str StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<Str> = std::__cxx11::basic_string<char>]
const lvalue
const
std::decay_t<Str> StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = const std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::decay_t<Str> = std::__cxx11::basic_string<char>; std::remove_reference_t<Str> = const std::__cxx11::basic_string<char>]
non-const
Str StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<Str> = std::__cxx11::basic_string<char>]
lvalue reference
non-const
Str StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<Str> = std::__cxx11::basic_string<char>]
const lvalue reference
const
std::decay_t<Str> StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = const std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::decay_t<Str> = std::__cxx11::basic_string<char>; std::remove_reference_t<Str> = const std::__cxx11::basic_string<char>]
non-const
Str StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<Str> = std::__cxx11::basic_string<char>]
rvalue
non-const
Str StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = std::__cxx11::basic_string<char>; <template-parameter-1-2> = void; std::remove_reference_t<Str> = std::__cxx11::basic_string<char>]
const rvalue
const
std::decay_t<Str> StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = const std::__cxx11::basic_string<char>; <template-parameter-1-2> = void; std::decay_t<Str> = std::__cxx11::basic_string<char>; std::remove_reference_t<Str> = const std::__cxx11::basic_string<char>]
non-const
Str StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<Str> = std::__cxx11::basic_string<char>]
rvalue reference
non-const
Str StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<Str> = std::__cxx11::basic_string<char>]
const rvalue reference
const
std::decay_t<Str> StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = const std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::decay_t<Str> = std::__cxx11::basic_string<char>; std::remove_reference_t<Str> = const std::__cxx11::basic_string<char>]
non-const
Str StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = std::__cxx11::basic_string<char>&; <template-parameter-1-2> = void; std::remove_reference_t<Str> = std::__cxx11::basic_string<char>]
string literal
non-const
Str StringReplace(Str&&, std::remove_reference_t<Str>&, std::remove_reference_t<Str>&) [with Str = std::__cxx11::basic_string<char>; <template-parameter-1-2> = void; std::remove_reference_t<Str> = std::__cxx11::basic_string<char>]