gpt4 book ai didi

c++ - 标准库实现是否允许具有与 C++ 标准不同的类定义?

转载 作者:IT老高 更新时间:2023-10-28 23:20:52 27 4
gpt4 key购买 nike

以下代码使用 clang 和 MSVC 成功编译,但在 GCC 6.1.0 中编译失败。

#include <memory>

template<typename R, typename T, typename... Args>
T* test(R(T::*)(Args...) const)
{
return nullptr;
}

int main()
{
using T = std::shared_ptr<int>;
T* p = test(&T::get);
}

带有以下错误信息

prog.cc: In function 'int main()':
prog.cc:13:16: error: invalid conversion from 'std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2u>*' to 'T* {aka std::shared_ptr<int>*}' [-fpermissive]
T* p = test(&T::get);
~~~~^~~~~~~~~

问题是 libstdc++ 实现了 std::shared_ptr通过继承成员函数get来自基类 std::__shared_ptr .

在C++标准20.8.2.2类模板shared_ptr中,它指定了std::shared_ptr类的类定义以及该类的所有成员函数。

我的问题是,实现是否必须至少在标准类内部提供标准中定义的所有公共(public)类成员?是否允许通过从libstdc++中实现的基类继承来提供成员函数?

最佳答案

标准对类型及其成员的规范是规范性文本,除非它明确另有说明。因此,需要一个实现来遵循……在某种程度上,一个实现需要遵循标准中的任何东西

这个范围就是“好像”规则。也就是说,只要类型表现得“好像”它按照指定的方式完成,实现就可以做它想做的事情。该标准具有特定语言说明类型可以从任意的、实现提供的基类派生的原因是因为这是用户可以检测到的东西。它是可见的行为(通过隐式转换等),因此标准必须做出异常(exception)以允许它。

继承成员几乎与在主类中声明成员相同。事实上,我所知道的唯一区别方法是做你在这里所做的:使用模板参数推导规则。即使您可以将成员指定为 Derived::get ,如果它真的来自某个基类,编译器就会知道。

然而,[member.functions] 在这里拯救了 GCC。它具有显式语言,允许标准库实现向类添加额外的重载。因此,您使用 std::shared_ptr<int>::get这里没有明确定义的行为。事实上,脚注 187 澄清了这一点:

Hence, the address of a member function of a class in the C++ standard library has an unspecified type.

这只是一个脚注,但意图似乎很明确:您不能依赖任何特定的实现来返回任何特定类型的成员指针。即使您对正确的签名应用了强制转换操作,也不能保证它会起作用。

因此,虽然标准库中的类定义是规范文本,但 [member.functions] 清楚地表明,唯一 您可以保证这些定义是您可以使用提供的论据。其他任何事情,比如获取成员指针,都是实现定义的。

关于c++ - 标准库实现是否允许具有与 C++ 标准不同的类定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38017567/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com