我有一段代码,我使用BaseFromMember成语来为我真正感兴趣的类(称为Derived
)创建一个正确的继承关系。我不知道在派生类的主体之前无法访问受保护(或私有)基类类型这一事实。请参阅下面的代码:
struct BaseFromMember
{
//protected: // comment/uncomment this line
using T = int; // using declaration/typedef
protected:
BaseFromMember()
: t_(1)
{}
const T& t() const { return t_; }
private:
const T t_;
};
template<class T>
class Base
{
public:
Base(const T& t)
{}
};
class Derived
: private BaseFromMember // private, protected, public doesn't matter here
, public Base<typename BaseFromMember::T> // this does not work for protected type T
{
using T = typename BaseFromMember::T; // works
public:
Derived()
: BaseFromMember()
, Base(BaseFromMember::t())
{}
};
int main()
{
Derived d;
}
正如预期的那样,问题不依赖于使用哪个修饰符从Derived
派生BaseFromMember
的事实。
但是,如果Base
中的using声明是公共的,则BaseFromMember
只能被初始化,否则gcc(4.8.2)和clang(3.4-1)都会出错。我认为这种行为是意外的,特别是因为typename BaseFromMember::T
可以在Derived
的正文中访问。
我无法在stackoverflow上找到任何相关主题。我找到了this thread,虽然我不确定它是否解决了同样的问题。
问题:我做错了什么或者我是否假设不应该假设的东西?或者这可能只是一个编译器错误?
注意:对我来说更令人不安的是,在建立typename
的继承时,关键字Derived
似乎没有任何影响。也许我只是做了一些非常愚蠢的事情?
注意:我不确定术语 initalization 在此上下文中是否正确,如此主题的标题中所使用的那样。如果另一个术语更合适,请告诉我。当然,我也想知道我使用的其他任何条款是否合适:)。
答案 0 :(得分:0)
这不是答案。
第一步可能是将代码缩减到更短的时间。我相信这段代码仍然展示了你描述的行为:
class A {
protected:
typedef int T;
};
template <typename T> class B {};
class C : public A, B<typename A::T> {};
实际上,这无法使用clang 3.4.1和gcc 4.8.2进行编译,而早期版本(4.5,4.6,4.7)很乐意接受它(我在C ++ 0x模式下运行每个编译器)。