【问题标题】:Private using declaration of base constructor is not private基构造函数的私有使用声明不是私有的
【发布时间】:2018-10-14 07:17:05
【问题描述】:

基构造函数的using 声明是私有的,但仍然可以构造该类。为什么?

对于必须公开的 operator[] 的 using 声明,辅助功能的工作方式不同。

#include <vector>

template<typename T>
class Vec : std::vector<T>
{
private:
    using std::vector<T>::vector;       // Works, even if private. Why?
public:
    using std::vector<T>::operator[];   // must be public
};

int main(){
    Vec<int> vec = {2, 2};
    auto test = vec[1];
}

如果我希望构造函数是私有的怎么办?可以通过using 声明来完成吗?

【问题讨论】:

  • @RemyLebeau 编译器生成的构造函数需要一个初始化列表?
  • 我不得不说我被否决票迷惑了。这是一个很好的问题,minimal reproducible example 等等。
  • 也许缺乏研究工作,因为 cppr 用简单的英语解释它@juanchopanza?无论如何,我想讨论它没有多大用处。

标签: c++ inheritance constructor using-declaration


【解决方案1】:

using reference 声明继承的构造函数

与相应的基本构造函数具有相同的访问权限。

它进一步暗示了这背后的基本原理:

如果用户定义的构造函数满足 constexpr 构造函数要求,则为 constexpr。如果相应的基础构造函数被删除,或者默认的默认构造函数将被删除,它就会被删除

显然,您不能显式地 constexpr 或 delete 继承构造函数,因此这些特征只是被继承了。访问级别也是如此。

【讨论】:

    【解决方案2】:

    基类构造函数的使用声明保持与基类相同的可访问性,无论基类的可访问性如何。来自[namespace.udecl]:

    使用声明创建的同义词具有成员声明的通常可访问性。命名构造函数的 using-declarator 不会创建同义词;相反,如果附加构造函数在用于构造相应基类的对象时可访问,则它们是可访问的,并且 using 声明的可访问性被忽略

    强调

    用简单的英语,from cppreference:

    它与相应的基本构造函数具有相同的访问权限。

    如果您希望“继承的”构造函数是私有的,则必须手动指定构造函数。你不能用 using 声明来做到这一点。

    【讨论】:

    • 好的,但这意味着访问带有初始化列表的基本构造函数是public。注意这个例子中的基类访问实际上是private。
    • 值得从标准中添加该段落的第一行。它解释了为什么 using std::vector&lt;T&gt;::operator[]; 需要在 public 部分中。
    • 问题实际上是关于保持继承的构造函数私有。似乎有了这个奇特的规则,仅仅使用using 声明是不可能实现的。或者一般更改访问权限。
    • “如果附加构造函数在用于构造相应基类的对象时可访问,则它们是可访问的”它们不应该是不可访问的,因为整个基类是一开始就无法访问?我似乎这部分实际上被解释为“不管用于继承的访问说明符”。
    猜你喜欢
    • 2019-10-16
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 2011-09-13
    相关资源
    最近更新 更多