Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions strings/base_implements.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,25 @@ namespace winrt::impl
template <typename D, typename I, typename Enable>
struct producer_convert : producer<D, typename default_interface<I>::type>
{
#ifdef __clang__
// This is sub-optimal in that it requires an AddRef and Release of the
// implementation type for every conversion, but it works around an
// issue where Clang ignores the conversion of producer_ref<I> const
// to I&& (an rvalue ref that cannot bind a const rvalue).
// See CWG rev. 110 active issue 2077, "Overload resolution and invalid
// rvalue-reference initialization"
operator I() const noexcept
{
I result{ nullptr };
copy_from_abi(result, (produce<D, typename default_interface<I>::type>*)this);
return result;
}
#else
operator producer_ref<I> const() const noexcept
{
return { (produce<D, typename default_interface<I>::type>*)this };
}
#endif

operator producer_vtable<I> const() const noexcept
{
Expand Down
10 changes: 10 additions & 0 deletions test/old_tests/UnitTests/as_implements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ TEST_CASE("as_implements")
REQUIRE(foo.get() == foo2.get());
}

TEST_CASE("as_implements_uniform_initialization")
{
// uniform initialization relies on IStringable(IStringable&&),
// which requires non-const rvalue semantics.
com_ptr<Foo> foo = make_self<Foo>();
IStringable stringable{ foo.as<IStringable>() };
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
IStringable stringable{ foo.as<IStringable>() };
IStringable stringable{ *foo };

Isn't something like this required to actually invoke the implicit conversion operator? Otherwise you're just calling the explicit as method provided by com_ptr which in turn calls QI.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

facepalm

com_ptr<Foo> foo2 = stringable.as<Foo>();
REQUIRE(foo.get() == foo2.get());
}

TEST_CASE("as_implements_inheritance")
{
com_ptr<Bar> bar = make_self<Bar>();
Expand Down