【发布时间】:2012-03-07 02:15:03
【问题描述】:
我们(应该)知道 C++ 标准库容器,包括 std::string,并不意味着继承自。但是,C++98/03 确实允许我们这样做,即使它会导致错误。
现在final 关键字可用,那些标有final 的标准库容器是否可以防止错误地使用它们的继承?
如果不是,那是为什么?
【问题讨论】:
我们(应该)知道 C++ 标准库容器,包括 std::string,并不意味着继承自。但是,C++98/03 确实允许我们这样做,即使它会导致错误。
现在final 关键字可用,那些标有final 的标准库容器是否可以防止错误地使用它们的继承?
如果不是,那是为什么?
【问题讨论】:
std::string 似乎没有被标记为 final,其他容器也没有。
我的猜测是为什么即使通常不推荐从它们派生,但没有人确定如果禁止它会破坏多少工作代码。
还要注意,对于它的价值,final 在技术上并不是一个关键词——它是一个附加了特殊含义的标识符,但仅限于特定情况下。包含int final; final = 1; 之类的代码仍然可以工作。不过,这主要是为了向后兼容——至少在新代码中,几乎可以肯定的是,将final 仅用于特殊含义,而不是作为普通标识符。
【讨论】:
int final; 并不令人困惑,在上下文中,我们确切地知道它的含义,所以没有问题。混淆只会发生在可以与表达式出现在同一位置的“关键字”上。这不是这里的情况。
LWG 在最近于 2012 年 2 月 6 日至 10 日在科纳举行的会议上讨论了这个问题。我是 LWG issue 2113。
LWG 决定将 LWG 2113 标记为 NAD(不是缺陷),理由是标准已经明确现有的类(例如容器和 std::string)不能被实现标记为 final。
讨论包括这样一个事实,虽然从这些类派生可能不受欢迎,但在 C++98/03 中这样做显然是合法的。在 C++11 中使其非法会破坏太多代码。
更新
此时,current working draft 中没有任何库类型被标记为final。
【讨论】:
std::string 和 std::vector 等类型在 C++11 之前可用。 std::future 是在 C++11 中引入的。你知道为什么新的 C++11 类没有作为最终类引入吗?为什么我问:使用像std::future 这样的类作为基类本质上并不是坏事,但另一方面,添加 final 会清楚地表明意图。那么什么是理性的not using final for classes in the standard library?
future 的私有继承非法。标准必须小心,不要演变成规定标准库之外代码的编码风格。