当前位置: 首页 > 知识库问答 >
问题:

在c 17标准中,使用名称空间std会导致boost指针转换触发ADL

公良骁
2023-03-14

我有一个简单的代码继承和shared_ptr从提升库。使用标准的c 20,代码编译良好。函数调用static_pointer_castdynamic_pointer_cast编译没有添加提升::命名空间-这些函数调用工作是因为ADL(参数依赖查找)。

但对于标准c 17,代码将无法编译。我会假设ADL没有实施,或者实施方式不同。但是,如果我使用名称空间std添加,代码就会编译得很好。我的问题是:std与boost库的函数调用有什么关系?

这是一个在线编译器,您可以通过使用名称空间std对<代码>进行注释来进行操作 行:https://godbolt.org/z/cz8Md5Ezf

#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

// using namespace std;

class Animal {
public:
  Animal()
  {}
  virtual ~Animal()
  {}
  void speak()
  {
    std::cout << "I am an animal\n";
  }
};

class Dog : public Animal {
public:
  Dog()
  {}
  void bark()
  {
    std::cout << "Gheu --> ";
  }
  void speak()
  {
    bark();
    Animal::speak();
  }
};

typedef boost::shared_ptr<Animal> AnimalPtr;
typedef boost::shared_ptr<Dog> DogPtr;

int main()
{
  AnimalPtr ap = boost::make_shared<Animal>();
  DogPtr dp = boost::make_shared<Dog>();

  AnimalPtr ap1 = static_pointer_cast<Animal>(dp);
  DogPtr dp1 = dynamic_pointer_cast<Dog>(ap1);

  return 0;
}

如果你在想,“好吧,如果使用命名空间std删除了错误,那么那些指针转换调用必须来自std库。”我也是这么想的。但是通过gdb查看,我发现不,使用命名空间std,这些函数肯定是从提升库调用的。


共有1个答案

秦才良
2023-03-14

当编译器看到<代码>

如果模板是通过通常的非限定名称查找(而非ADL)找到的,则假定是后者。但如果找不到模板怎么办?

在C 20之前,如果查找没有找到模板,则假定名称没有引用模板,并且以下代码

在您原来的情况下,这是没有意义的。例如,没有什么static_pointer_cast可以引用为的操作数

使用名称空间std 编译器可能会隐式地包含std::static\u pointer\u cast(来自

从C 20开始,如果查找没有找到任何内容或根本没有找到任何函数,那么也假设a

通过将解释作为模板参数列表,从而进行函数调用,将完成非限定函数调用的常规非限定名称查找和ADL,如果您使用的是命名空间std,则会查找(通过ADL)boost::shared\u pointer\u cast和(通过ADL)shared\u pointer\u cast,但由于您正在传递一个boost::shared\u ptr,因此需要一个std::shared\u ptr参数的std版本将不可行,并且总是通过重载解析来选择boost版本。此部分与C 20保持不变。

注意,这是C 20中的一个突破性变化。在一些非常常见的情况下,您可能希望

 类似资料:
  • 问题内容: 我最近正在学习Java并发编程。我知道关键字可以保证安全的发布。但是,当我阅读源代码时,发现and 字段未使用关键字。我发现该方法在方法中被调用,并且该方法直接将值分配给。此时,可能是因为未使用声明。我的理解正确吗?虽然可以保证读写线程的安全性,但是可以 保证不是一个正确的初始值 问题答案: 根据此博客文章https://shipilev.net/blog/2014/safe-publ

  • 我一直在youtube上学习android的自定义视图等等。在我尝试做一个表面视图(相当简单的描述在这个视频)。 我所做的事情与视频中所显示的几乎是同步的。

  • 问题内容: 我试图发出带有元素树的XML文件,其中包含XML声明和名称空间。这是我的示例代码: 但是,既不会出现标签,也不会出现任何名称空间/前缀信息。我在这里有点困惑。 问题答案: 尽管文档另有说明,但我只能通过同时指定xml_declaration和编码来获得声明。 您必须在已注册的名称空间中声明节点,以在文件中的节点上获取名称空间。这是您的代码的固定版本: 输出(page.xml) Elem

  • 我有以下XML,我能够根据预期输出进行转换和分组,但当我尝试使用命名空间xmlns时=”http://oracle.com/SGGIMDsEvents“但从未奏效。遵循xml示例输入 XSLT代码-对某些部分进行注释只是为了进行命名空间测试,否则效果很好。这里有一个链接,可以在没有命名空间的情况下运行此代码URL-https://xsltfiddle.liberty-development.net

  • 问题内容: 解决在Java中包含名称空间的xpath似乎需要使用一个对象,将前缀映射到名称空间url,反之亦然。但是,除了自己实现之外,我找不到其他机制。这似乎违反直觉。 问题: 是否有任何简单的方法可以从文档中获取文档,或者创建文档,或者失败文档,以完全放弃前缀并使用完全限定的名称指定xpath? 问题答案: 无需编写自己的类就可以获取 NamespaceContext 实例。它的类使用页面显示

  • 问题内容: 这两行之间的主要区别是什么: 和 当我使用第一行时,我得到一个错误:而且我不太确定为什么会收到此错误?第二行似乎已解决了该问题。 问题答案: 如果您使用: 这意味着ArrayObject是在当前名称空间中定义的。您可以在全局名称空间(当前作用域中未定义名称空间)中,或者在与当前作用域相同的名称空间中定义ArrayObject时,使用此语法(示例)。 如果您使用: 这意味着ArrayOb