Is there a way to specify all classes in a variadic parameter pack to be friend of the template in order to use operator=?

心已入冬 提交于 2020-12-02 17:02:26

问题


I have seen a CRTP solution, which extracted the interface into the base class, and friended only one of the pack arguments per base class. Then the most derived class inherited all the friended base classes and implemented the interface.

I cannot use this approach, since I need to protect the assignment operator, which is not inherited.

Also, since the assignment operator has a defined signature with exactly one parameter, I cannot use a key pattern.

This is what I would like to have:

template <typename... F>
struct A {
protected:
    A& operator=(const SomeClass &other) {
        //...
    }
private:
    //I would like to do the following, but it does not work
    friend F...;
}

Is there a way to do what I am needing?


回答1:


Well, you can always play dirty. First, define a repetition macro:

#define REPEAT_2(M, N) M(N) M(N+1)
#define REPEAT_4(M, N)   REPEAT_2  (M, N) REPEAT_2(M, N+2)
#define REPEAT_8(M, N)   REPEAT_4  (M, N) REPEAT_4(M, N+4)
#define REPEAT_16(M, N)  REPEAT_8  (M, N) REPEAT_8(M, N+8)
#define REPEAT_32(M, N)  REPEAT_16 (M, N) REPEAT_16(M, N+16)
#define REPEAT_64(M, N)  REPEAT_32 (M, N) REPEAT_32(M, N+32)
#define REPEAT_128(M, N) REPEAT_64 (M, N) REPEAT_64(M, N+64)

Then place 128 friend declarations into a variadic class template of your choice:

template <typename... T>
class A
{
    #define FRIEND(N) friend std::tuple_element_t<
                       std::min((std::size_t)N+1, sizeof...(T)), std::tuple<void, T...>>;
    REPEAT_128(FRIEND, 0)

    static constexpr int i = 3;
};

struct X; struct Y; struct Z;
using ASpec = A<X, Y, Z>;
struct X {int i = ASpec::i;};
struct Y {int i = ASpec::i;};
struct Z {int i = ASpec::i;};

template class A<>; // Small test for empty pack

Demo. Credit to @dyp.

If you have access to Boost.Preprocessor, the entire thing can be written far more concisely using BOOST_PP_REPEAT.



来源:https://stackoverflow.com/questions/31510844/is-there-a-way-to-specify-all-classes-in-a-variadic-parameter-pack-to-be-friend

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!