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
110
110
template <typename D, typename I, typename Enable>
111
111
struct producer_convert : producer<D, typename default_interface<I>::type>
112
112
{
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
113
127
operator producer_ref<I> const () const noexcept
114
128
{
115
129
return { (produce<D, typename default_interface<I>::type>*)this };
116
130
}
131
+ #endif
117
132
118
133
operator producer_vtable<I> const () const noexcept
119
134
{
Original file line number Diff line number Diff line change @@ -138,3 +138,13 @@ TEST_CASE("as_implements_inheritance")
138
138
REQUIRE (bar.get () == foo2.get ());
139
139
}
140
140
}
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