有没有办法指定可变参数包中的所有 类 成为模板的友元以便使用 operator=?
Is there a way to specify all classes in a variadic parameter pack to be friend of the template in order to use operator=?
我看到了一个 CRTP solution,它将接口提取到基 class 中,并且每个基 class 只加了一个包参数。然后最派生的class继承了所有的友基classes并实现了接口
我不能使用这种方法,因为我需要保护不能继承的赋值运算符。
此外,由于赋值运算符定义的签名只有一个参数,所以我不能使用 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 个朋友声明放入您选择的可变 class 模板中:
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
.
更简洁地编写整个内容
我看到了一个 CRTP solution,它将接口提取到基 class 中,并且每个基 class 只加了一个包参数。然后最派生的class继承了所有的友基classes并实现了接口
我不能使用这种方法,因为我需要保护不能继承的赋值运算符。
此外,由于赋值运算符定义的签名只有一个参数,所以我不能使用 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 个朋友声明放入您选择的可变 class 模板中:
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
.