@@ -979,9 +979,15 @@ auto as( X const& x ) -> decltype(auto) {
979
979
return x;
980
980
}
981
981
982
+ template < typename C, typename X >
983
+ requires std::is_same_v<C, X>
984
+ auto as ( X& x ) -> decltype(auto ) {
985
+ return x;
986
+ }
987
+
982
988
template < typename C, typename X >
983
989
auto as ( X const & x ) -> auto
984
- requires (!std::is_same_v<C, X> && requires { C{x}; })
990
+ requires (!std::is_same_v<C, X> && !std::is_base_of_v<C, X> && requires { C{x}; })
985
991
{
986
992
// Experiment: Recognize the nested `::value_type` pattern for some dynamic library types
987
993
// like std::optional, and try to prevent accidental narrowing conversions even when
@@ -995,9 +1001,15 @@ auto as( X const& x ) -> auto
995
1001
}
996
1002
997
1003
template < typename C, typename X >
998
- requires std::is_base_of_v<C, X>
999
- auto as ( X&& x ) -> C&& {
1000
- return CPP2_FORWARD (x);
1004
+ requires (std::is_base_of_v<C, X> && !std::is_same_v<C, X>)
1005
+ auto as( X& x ) -> C& {
1006
+ return x;
1007
+ }
1008
+
1009
+ template < typename C, typename X >
1010
+ requires (std::is_base_of_v<C, X> && !std::is_same_v<C, X>)
1011
+ auto as( X const & x ) -> C const & {
1012
+ return x;
1001
1013
}
1002
1014
1003
1015
template < typename C, typename X >
0 commit comments