Skip to content

The generated 'operator==' of a struct with an 'IReference<T>' member is sensitive to inclusion/include order #801

@dunhor

Description

@dunhor

E.g. consider the following:

namespace Component
{
    struct Test
    {
        IReference<Int32> member;
    };
}

Then the generated file winrt/impl/Component.2.h will include an operator== definition that looks something like:

    inline bool operator==(Test const& left, Test const& right) noexcept
    {
        return left.member == right.member;
    }

It seems that the intended functionality is that the above uses the operator== defined for IReference<T>:

    template <typename T>
    bool operator==(IReference<T> const& left, IReference<T> const& right)
    {
        if (get_abi(left) == get_abi(right))
        {
            return true;
        }

        if (!left || !right)
        {
            return false;
        }

        return left.Value() == right.Value();
    }

This works fine, however the issue lies in the fact that the above operator== for IReference<T> is defined in winrt/Windows.Foundation.h. This file is included by neither winrt/Component.h nor winrt/impl/Component.2.h. Both - curiously enough - include winrt/impl/Windows.Foundation.2.h, however the desired function definition is not present in this file.

The end result is that winrt/Windows.Foundation.h must be explicitly included before winrt/Component.h for it to work properly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions