不应该禁止使用私有类型吗?

MFn*_*Fnx 5 c++ c++11 c++03

考虑以下代码:

class A
{
    struct B {};
    std::vector<B> _vec;

public:
    const std::vector<B>& get() const { return _vec; }
};
Run Code Online (Sandbox Code Playgroud)

请注意,这B在class 中是私有的A。上面的代码可以编译,但是get()从外部类调用时A,它不会:

const std::vector<A::B>& vec = get(); // does not compile
Run Code Online (Sandbox Code Playgroud)

确实A::Bprivate。但是,从此以后C++11,您可以简单地执行以下操作:

const auto& vec = get();
Run Code Online (Sandbox Code Playgroud)

完美地运作。

由于与上述相同的原因,您不能执行以下操作:

A::B obj; 
Run Code Online (Sandbox Code Playgroud)

但是,由于存在一个public吸气剂,您可以从该吸气剂功能推导出类型。在这种情况下,可以执行以下操作:

using B = std::decay<decltype(C{}.get())>::type::value_type;
B obj;
Run Code Online (Sandbox Code Playgroud)

问题

我不确定如何提出我的问题。从C ++ 11开始(而不是之前),我实际上可以实例化为A::B后者,这对我来说似乎很奇怪private。而且,我认为我们可以打电话叫怪const auto& get()。有什么解释吗?不允许这样做不是更好吗?我应该申报A::B public吗?我觉得private如果需要像上面代码中那样的getter函数,则声明它没有任何意义。

Nic*_*las 3

我觉得奇怪的是,从 C++11 开始(而不是之前),我们实际上可以将 A::B 实例化为后者私有。

您可以在 C++98/03 中通过模板参数推导来完成此操作:

template<typename T>
void temp_func(const T &t)
{
...
T u = t;
}

temp_func(a.get()); //Will use the private type.
Run Code Online (Sandbox Code Playgroud)

您甚至可以Ttemp_func.

将类型设置为私有并不能保证该类型无法从外部访问。Private 始终指的是名称的可访问性而不是名称背后的构造的可访问性。如果您希望某个类型仅在某个范围内使用,则该类型名不能是任何非私有接口的一部分。情况一直如此。

我应该A::B公开吗?

这取决于你。但是,如果您公开一个公共用户界面,那么您就是在声明用户可以(您知道)使用该界面。为了让用户知道如何使用vector<A::B>,他们必须知道它的A::B行为方式。所以他们必须使用它的定义。尽管这是私人的。

因此,如果用户必须了解类型以及类型的行为方式……它真的是“私有的”吗?