File tree Expand file tree Collapse file tree 2 files changed +25
-0
lines changed
Expand file tree Collapse file tree 2 files changed +25
-0
lines changed Original file line number Diff line number Diff line change @@ -110,10 +110,25 @@ namespace winrt::impl
110110 template <typename D, typename I, typename Enable>
111111 struct producer_convert : producer<D, typename default_interface<I>::type>
112112 {
113+ #ifdef __clang__
114+ // This is sub-optimal in that it requires an AddRef and Release of the
115+ // implementation type for every conversion, but it works around an
116+ // issue where Clang ignores the conversion of producer_ref<I> const
117+ // to I&& (an rvalue ref that cannot bind a const rvalue).
118+ // See CWG rev. 110 active issue 2077, "Overload resolution and invalid
119+ // rvalue-reference initialization"
120+ operator I () const noexcept
121+ {
122+ I result{ nullptr };
123+ copy_from_abi (result, (produce<D, typename default_interface<I>::type>*)this );
124+ return result;
125+ }
126+ #else
113127 operator producer_ref<I> const () const noexcept
114128 {
115129 return { (produce<D, typename default_interface<I>::type>*)this };
116130 }
131+ #endif
117132
118133 operator producer_vtable<I> const () const noexcept
119134 {
Original file line number Diff line number Diff line change @@ -138,3 +138,13 @@ TEST_CASE("as_implements_inheritance")
138138 REQUIRE (bar.get () == foo2.get ());
139139 }
140140}
141+
142+ TEST_CASE (" convert_to_implements_via_uniform_initialization" )
143+ {
144+ // uniform initialization relies on IStringable(IStringable&&),
145+ // which requires non-const rvalue semantics.
146+ com_ptr<Foo> foo = make_self<Foo>();
147+ IStringable stringable{ *foo };
148+ com_ptr<Foo> foo2 = stringable.as <Foo>();
149+ REQUIRE (foo.get () == foo2.get ());
150+ }
You can’t perform that action at this time.
0 commit comments