Index: src/mpt/string/types.hpp
===================================================================
--- src/mpt/string/types.hpp	(revision 18621)
+++ src/mpt/string/types.hpp	(working copy)
@@ -14,6 +14,7 @@
 #include <string>
 #include <string_view>
 #include <type_traits>
+#include <utility>
 
 #include <cstddef>
 
@@ -504,11 +505,11 @@
 
 
 template <typename T>
-inline typename mpt::make_string_type<T>::type as_string(const T & str) {
-	if constexpr (std::is_pointer<typename std::remove_cv<T>::type>::value) {
-		return str ? typename mpt::make_string_type<T>::type{str} : typename mpt::make_string_type<T>::type{};
-	} else if constexpr (mpt::is_string_view_type<T>::value) {
-		return typename mpt::make_string_type<T>::type{str};
+inline typename mpt::make_string_type<typename std::decay<T>::type>::type as_string(T && str) {
+	if constexpr (std::is_pointer<typename std::decay<T>::type>::value) {
+		return str ? typename mpt::make_string_type<typename std::decay<T>::type>::type{std::forward<T>(str)} : typename mpt::make_string_type<typename std::decay<T>::type>::type{};
+	} else if constexpr (mpt::is_string_view_type<typename std::decay<T>::type>::value) {
+		return typename mpt::make_string_type<typename std::decay<T>::type>::type{std::forward<T>(str)};
 	} else {
 		return str;
 	}
@@ -517,11 +518,11 @@
 
 
 template <typename T>
-inline typename mpt::make_string_view_type<T>::type as_string_view(const T & str) {
-	if constexpr (std::is_pointer<typename std::remove_cv<T>::type>::value) {
-		return str ? typename mpt::make_string_view_type<T>::type{str} : typename mpt::make_string_view_type<T>::type{};
-	} else if constexpr (mpt::is_string_view_type<T>::value) {
-		return typename mpt::make_string_view_type<T>::type{str};
+inline typename mpt::make_string_view_type<typename std::decay<T>::type>::type as_string_view(T && str) {
+	if constexpr (std::is_pointer<typename std::decay<T>::type>::value) {
+		return str ? typename mpt::make_string_view_type<typename std::decay<T>::type>::type{std::forward<T>(str)} : typename mpt::make_string_view_type<typename std::decay<T>::type>::type{};
+	} else if constexpr (mpt::is_string_view_type<typename std::decay<T>::type>::value) {
+		return typename mpt::make_string_view_type<typename std::decay<T>::type>::type{std::forward<T>(str)};
 	} else {
 		return str;
 	}
Index: src/mpt/string_transcode/transcode.hpp
===================================================================
--- src/mpt/string_transcode/transcode.hpp	(revision 18621)
+++ src/mpt/string_transcode/transcode.hpp	(working copy)
@@ -25,6 +25,7 @@
 #if !defined(MPT_COMPILER_QUIRK_NO_WCHAR)
 #include <type_traits>
 #endif // !MPT_COMPILER_QUIRK_NO_WCHAR
+#include <utility>
 #include <vector>
 
 #if MPT_OS_DJGPP
@@ -1891,28 +1892,28 @@
 
 #endif // MPT_DETECTED_MFC
 
-template <typename Tdststring, typename Tsrcstring, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<Tsrcstring>::type>::value, bool> = true>
-inline Tdststring transcode(const Tsrcstring & src) {
-	if constexpr (std::is_same<Tdststring, typename mpt::make_string_type<Tsrcstring>::type>::value) {
-		return mpt::as_string(src);
+template <typename Tdststring, typename Tsrcstring, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type>::value, bool> = true>
+inline Tdststring transcode(Tsrcstring && src) {
+	if constexpr (std::is_same<Tdststring, typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type>::value) {
+		return mpt::as_string(std::forward<Tsrcstring>(src));
 	} else {
-		return string_transcoder<Tdststring>::encode(string_transcoder<decltype(mpt::as_string(src))>::decode(mpt::as_string(src)));
+		return string_transcoder<Tdststring>::encode(string_transcoder<decltype(mpt::as_string(std::forward<Tsrcstring>(src)))>::decode(mpt::as_string(std::forward<Tsrcstring>(src))));
 	}
 }
 
-template <typename Tdststring, typename Tsrcstring, typename Tencoding, std::enable_if_t<std::is_same<Tdststring, std::string>::value, bool> = true, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<Tsrcstring>::type>::value, bool> = true>
-inline Tdststring transcode(Tencoding to, const Tsrcstring & src) {
-	return mpt::encode<Tdststring>(to, string_transcoder<decltype(mpt::as_string(src))>::decode(mpt::as_string(src)));
+template <typename Tdststring, typename Tsrcstring, typename Tencoding, std::enable_if_t<std::is_same<Tdststring, std::string>::value, bool> = true, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type>::value, bool> = true>
+inline Tdststring transcode(Tencoding to, Tsrcstring && src) {
+	return mpt::encode<Tdststring>(to, string_transcoder<decltype(mpt::as_string(std::forward<Tsrcstring>(src)))>::decode(mpt::as_string(std::forward<Tsrcstring>(src))));
 }
 
-template <typename Tdststring, typename Tsrcstring, typename Tencoding, std::enable_if_t<std::is_same<typename mpt::make_string_type<Tsrcstring>::type, std::string>::value, bool> = true, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<Tsrcstring>::type>::value, bool> = true>
-inline Tdststring transcode(Tencoding from, const Tsrcstring & src) {
-	return string_transcoder<Tdststring>::encode(mpt::decode<decltype(mpt::as_string(src))>(from, mpt::as_string(src)));
+template <typename Tdststring, typename Tsrcstring, typename Tencoding, std::enable_if_t<std::is_same<typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type, std::string>::value, bool> = true, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type>::value, bool> = true>
+inline Tdststring transcode(Tencoding from, Tsrcstring && src) {
+	return string_transcoder<Tdststring>::encode(mpt::decode<decltype(mpt::as_string(std::forward<Tsrcstring>(src)))>(from, mpt::as_string(std::forward<Tsrcstring>(src))));
 }
 
-template <typename Tdststring, typename Tsrcstring, typename Tto, typename Tfrom, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<Tsrcstring>::type>::value, bool> = true>
-inline Tdststring transcode(Tto to, Tfrom from, const Tsrcstring & src) {
-	return mpt::encode<Tdststring>(to, mpt::decode<decltype(mpt::as_string(src))>(from, mpt::as_string(src)));
+template <typename Tdststring, typename Tsrcstring, typename Tto, typename Tfrom, std::enable_if_t<mpt::is_string_type<typename mpt::make_string_type<typename std::decay<Tsrcstring>::type>::type>::value, bool> = true>
+inline Tdststring transcode(Tto to, Tfrom from, Tsrcstring && src) {
+	return mpt::encode<Tdststring>(to, mpt::decode<decltype(mpt::as_string(std::forward<Tsrcstring>(src)))>(from, mpt::as_string(std::forward<Tsrcstring>(src))));
 }
 
 
