C++ 使用';使用';关键字将继承的构造函数公开

C++ 使用';使用';关键字将继承的构造函数公开,c++,inheritance,testing,c++11,using,C++,Inheritance,Testing,C++11,Using,我正在尝试测试类的受保护方法和构造函数。为此,我尝试将其子类化,并使用C++11使用关键字将其成员重新导出为public: class Foo { protected: Foo(int i) {} void run() {} }; class TestableFoo : public Foo { public: using Foo::Foo; using Foo::run; }; int main() { TestableFoo foo(7); foo

我正在尝试测试类的受保护方法和构造函数。为此,我尝试将其子类化,并使用C++11
使用
关键字将其成员重新导出为public:

class Foo {
  protected:
   Foo(int i) {}
   void run() {}
};

class TestableFoo : public Foo {
  public:
   using Foo::Foo;
   using Foo::run;
};

int main() {
  TestableFoo foo(7);
  foo.run();
}
但是,g++和clang++都未能编译它,从而产生以下错误:

test.cpp:13:15: error: ‘TestableFoo::TestableFoo(int)’ is protected
    using Foo::Foo;
               ^
test.cpp:18:16: error: within this context
   TestableFoo foo(7);
                    ^

TestableFoo构造函数仍然受到保护,即使
run
方法公开(我单独确认了)。为什么会这样?我可以理解这两种决定(继承还是覆盖可见性),但为什么方法和构造函数之间存在不一致?

标准明确规定继承的构造函数保留其访问级别:

12.9继承构造函数[class.inhctor]

1使用隐式命名构造函数的声明(7.3.3) 声明一组继承构造函数。候选集 继承了using声明中命名的类
X
的构造函数 由实际构造函数和产生结果的概念构造函数组成 默认参数的转换如下所示:

[案件清单略去]

4这样声明的构造函数与相应的构造函数具有相同的访问权限 X中的构造函数。如果
X
已删除(8.4)

当然,你可以直接叫它:

TestableFoo(int i) : Foo(i) { }

该行为符合标准规定(ISO/IEC 14822:2011 12.9,§4):

这样声明的构造函数与X中相应的构造函数具有相同的访问权限

其中
X
是继承构造函数的基类

要获得所需的行为,您可以使用:

class TestableFoo : public Foo {
  public :
    TestableFoo(int i) : Foo(i) { }
    using Foo::run;
};
相关--但没有回答为什么“为什么”可能是因为否则它会改变所有构造函数的可访问性,这可能被认为是比在这种情况下无法继承它们更糟糕的问题。但这只是一个猜测。