是否有一种技术可以让匿名结构的命名实例引用封闭 class 内的函数?
Is there a technique for named instances of an anonymous struct to reference functions inside the enclosing class?
我有一个 CRTP class,为了 API 重构期间的清晰度,我想要一个包含方法的命名匿名结构,而不是让所有方法都在 class 范围内。问题是,这些方法需要访问外部范围。例如:
template<typename T>
class sample_class {
public:
struct {
void do_something() {
auto& result = get_ref().something_else(); //get_ref() out of inner struct scope
...
}
} inner;
private:
T& get_ref() { return static_cast<T&>(*this); }
};
有什么技巧可以做到这一点吗?特别是 C++14 和 gcc7,因为我不相信匿名结构在技术上符合标准。
另一个 class 中的 class 没有指向封闭 class 的 this 指针的隐式指针。
如果您希望它具有指向封闭 class 实例的指针,请显式存储它。
struct {
void do_something() {
auto& result = p_sample->get_ref().something_else(); //get_ref() out of inner struct scope
...
}
sample* p_sample;
} inner;
或传入指向方法的指针:
void do_something(sample* psample) {
auto& result = p_sample->get_ref().something_else(); //get_ref() out of inner struct scope
...
}
有一些方法可以使用指针运算来生成看似指向外部的指针 class,但它们被 C++ 中极其复杂和危险的规则所困。
除了一些 access/naming 规则之类的,其他 classes 中定义的 classes 并不是魔法。它们可以(理论上)存在于其他环境中; inner
可以存在于堆栈中的某处,而不是 sample
.
中
是的,你从this
中减去offsetof
的结果:
auto &self = *reinterpret_cast<sample_class *>(reinterpret_cast<char *>(this) - offsetof(sample_class, inner));
这在技术上可能是 UB(请参阅 std::launder
的可达性规则),但在实践中应该足够好。
但我认为获得 nice-looking 方法名称并不能保证这种骇客行为。只需将 inner.do_something()
替换为 inner_do_something()
.
我有一个 CRTP class,为了 API 重构期间的清晰度,我想要一个包含方法的命名匿名结构,而不是让所有方法都在 class 范围内。问题是,这些方法需要访问外部范围。例如:
template<typename T>
class sample_class {
public:
struct {
void do_something() {
auto& result = get_ref().something_else(); //get_ref() out of inner struct scope
...
}
} inner;
private:
T& get_ref() { return static_cast<T&>(*this); }
};
有什么技巧可以做到这一点吗?特别是 C++14 和 gcc7,因为我不相信匿名结构在技术上符合标准。
另一个 class 中的 class 没有指向封闭 class 的 this 指针的隐式指针。
如果您希望它具有指向封闭 class 实例的指针,请显式存储它。
struct {
void do_something() {
auto& result = p_sample->get_ref().something_else(); //get_ref() out of inner struct scope
...
}
sample* p_sample;
} inner;
或传入指向方法的指针:
void do_something(sample* psample) {
auto& result = p_sample->get_ref().something_else(); //get_ref() out of inner struct scope
...
}
有一些方法可以使用指针运算来生成看似指向外部的指针 class,但它们被 C++ 中极其复杂和危险的规则所困。
除了一些 access/naming 规则之类的,其他 classes 中定义的 classes 并不是魔法。它们可以(理论上)存在于其他环境中; inner
可以存在于堆栈中的某处,而不是 sample
.
是的,你从this
中减去offsetof
的结果:
auto &self = *reinterpret_cast<sample_class *>(reinterpret_cast<char *>(this) - offsetof(sample_class, inner));
这在技术上可能是 UB(请参阅 std::launder
的可达性规则),但在实践中应该足够好。
但我认为获得 nice-looking 方法名称并不能保证这种骇客行为。只需将 inner.do_something()
替换为 inner_do_something()
.