我正在尝试从模板中公开派生一个类,这将使它从基类继承并获得对 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/