c++ - 在扩展派生自的模板之前访问模板的基类

标签 c++ templates inheritance protected

我正在尝试从模板中公开派生一个类,这将使它从基类继承并获得对 protected 成员的访问权限。但是在模板展开之前它没有这些权限,所以它不能使用 Base 成员作为模板参数:

using Fun = void (*)();

class Base {
protected:
    // friend class Derived; // ...need this to eliminate complaint
    static void something();
};

template<Fun F>
class Variant : public Base {};

class Derived : public Variant<&Base::something> { // `something()` is protected
public:
    void somethingElse() {
        something(); // doesn't complain about this `something()`
    }
};

int main() {}

对我来说奇怪的一点是交友功能完全有效。我想知道我是否可以通过在 Variant 之前放置一个来自 Base 的公共(public)虚拟继承来“偷偷进入 Derived 门”:

class Derived : public virtual Base, public Variant<&Base::something>

那没有帮助。

问题:是否有其他一些技巧可以避免显式提及 Base 中的所有派生类,但仍然可以从中选择 protected 成员作为模板参数?

(注意:在较旧的 gcc 4.6.3 上尝试此操作,看起来在这种情况下即使是好友也无济于事。因此似乎对它的支持有点新。)

最佳答案

将违规访问粘贴到元函数中。从基派生元函数类。

template<typename B>
struct something_variant : public B {
    typedef Variant< & B::something > type;
};

class Derived : public something_variant<Base>::type {
    …

http://coliru.stacked-crooked.com/a/6bca00455bd3daca

关于 CWG 372,决议中的关键文本是这样的:

[A]ccess checking of base-specifiers must be deferred until the entire base-specifier-list has been seen.

这已在 C++11 中被接受,因此您的示例被拒绝很有趣。而且,plugging 从 C++11 标准到最近的 Clang 和 GCC 的相关示例代码表明它们根本没有实现延迟。这至少有点不足为奇,因为实现需要一些数据结构来表示一组延迟访问检查……对于极端情况来说相当费力。

关于c++ - 在扩展派生自的模板之前访问模板的基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32983193/

相关文章:

c++ - c++模板语法解释

c# - .Net - 如何创建实现接口(interface)的 UserControl?负载控制错误

c++ - Bison :存储自定义类

c++ - 为什么 C 字 rune 字是 int 而不是 char?

c++ - 这段代码发生了什么?

c# - 我可以防止类被非抽象对象继承吗?

c++ - 我可以让静态函数继承每个类的特定值吗?

c++ - 如果我有一点其他编程经验,学习 C++ 的最佳方式是什么?

C++ 数组作为函数参数

c++ - 使用 C++11 auto 关键字声明两个(或更多)变量