为什么std :: future和std :: promise不是最终的?

Son*_*c78 14 c++ language-lawyer c++11 c++14

我为为什么类std::futurestd::promise不用final说明符标记感到烦恼。该析构函数不是虚拟的,这样为什么final不加入?基本原理是什么?

lub*_*bgr 19

看一下这个人为的(当然是荒谬的)示例std::vector

template <class T>
struct Example : private std::vector<T> {
   void doStuff(const T& t) { this->push_back(t); }
   T retrieveStuff() { return this->operator[](0); }
};

Example<int> e;

e.doStuff(42);
std::cout << e.retrieveStuff() << "\n";
Run Code Online (Sandbox Code Playgroud)

这行得通,您不能进入UB std::vector::~vectorvirtual因为您不能通过基类指针删除对象(public在那里需要继承)。

这里的继承只是实现细节。不推荐这样做,但是人们可能这样做了。一旦决定不通过make std::vector或其他容器类型破坏现有代码final,便坚持使用不同的词汇类型(如std::promise或)有意义std::future

  • @Mirko“调用基类非虚拟析构函数没有问题”真的吗?还是您尝试过的所有时间都“看起来不错”? (7认同)
  • @Mirko该示例旨在仅显示一些与OP的问题相关的非格式,非UB用例。而public继承为UB打开了大门,因为它允许调用非virtual析构函数。 (3认同)
  • @Mirko您可以将语义添加到需要调用适当析构函数的派生类中,而无需增加类的大小,因此您的“ static_assert”不一定足够。在任何情况下,答案的重点都不是显示从_something_继承的_best_方式,而只是显示从`std :: vector`派生的_legal_方式。 (2认同)

P.W*_*P.W 16

根据[推导] / 4

除非另有说明,否则C ++标准库中指定的所有类型均应为非最终类型

std::futurestd::promise不排除在外。

正如评论中提到的那样,此问题之前已经讨论过。库实现者是否可以自由地将final添加到非多态组件?

解决此问题的方法是,该结论不被认为是缺陷:

除非库final在规范中使用关键字,否则用户显然可以自由地从此类中派生,因此同样清楚地,库供应商也无权添加final重写器或类属性。