Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

export friend from template to global namespace

Tags:

c++

templates

Is any way to export friend from template to global namespace without forward declaration?

template <typename T>
struct flags {
    static_assert(std::is_enum_v<T>);

    using base = std::underlying_type_t<T>;

    friend T operator|(const T lhs, const T rhs) {
        return T(base(lhs) | base(rhs));
    }
};

enum class MyEnum {
    A,
    B
};

template struct flags<MyEnum>;

auto operator|(MyEnum, MyEnum) -> MyEnum; // (1)

MyEnum myEnum = MyEnum::A | MyEnum::B; //Not compile without (1)
like image 346
Max Pasichnyk Avatar asked Jan 04 '20 19:01

Max Pasichnyk


1 Answers

Let me preface this by saying that it is a nice and imaginative idea for code generation. But there is no way to expose the friend function for argument dependent lookup.

The problem is that ADL only considers friends of associated namespaces and class types. For an enumeration to be associated with a class type, it must be a member of the class, i.e. a member of a flags specialization. There is no way to associate an enum with a class type (for ADL purposes) otherwise.

In your use case the enumeration is obviously not intended to be a member of flags<MyEnum>, so friend functions of flags<MyEnum> are not going to be considered in overload resolution that involves just MyEnum.

like image 57
StoryTeller - Unslander Monica Avatar answered Nov 15 '22 21:11

StoryTeller - Unslander Monica