我已经看到了一个
CRTP solution,它将接口提取到基类中,并且只为每个基类提供了一个包参数.然后,派生程度最高的类继承了所有friended基类并实现了接口.
我不能使用这种方法,因为我需要保护赋值运算符,它不是继承的.
此外,由于赋值运算符具有仅具有一个参数的已定义签名,因此我无法使用key pattern.
这就是我想要的:
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...; }
有办法做我需要的吗?
解决方法
好吧,你总是玩脏.首先,定义一个重复宏:
#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)
然后将128个好友声明放入您选择的可变参数类模板中:
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.归功于@dyp.
如果您可以访问Boost.Preprocessor,则可以使用BOOST_PP_REPEAT更简洁地编写整个内容.