是否有一种技术可以让匿名结构的命名实例引用封闭 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().