什么是C ++名称查找在这里做什么? (&是GCC吗?)

时间:2015-04-08 19:38:03

标签: c++ argument-dependent-lookup

我在某些生产代码中出现问题,我将其最小化为以下测试用例:

template<typename T>
void intermediate(T t)
{
    func(t); // line 4 ("func not declared in this scope")
}

namespace ns {
    struct type {};
}

void func(ns::type const & p); // line 11 ("declared here, later")

void foo(ns::type exit_node)
{
    intermediate(exit_node);  // line 15 ("required from here")
}

GCC 4.5编译此罚款。有和没有-std=c++11,4.7和4.9都会产生如下消息:

test.cpp: In instantiation of ‘void intermediate(T) [with T = ns::type]’:
test.cpp:15:27:   required from here
test.cpp:4:5: error: ‘func’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
test.cpp:11:6: note: ‘void func(const ns::type&)’ declared here, later in the translation unit

以下所有三件事都会导致文件成功编译:

  1. func(ns::type)移至ns命名空间(允许ADL在ns中找到它)
  2. type移至全局命名空间(允许ADL在::中找到它)
  3. 摆脱intermediate并直接从func
  4. 致电foo

    那么......这里发生了什么?海湾合作委员会拒绝该计划是否合法?为什么func在第三个变体中通过非限定查找找到(直接从func调用foo),但在实例化时原始变体中的非限定查找找不到?

2 个答案:

答案 0 :(得分:7)

一般规则是,模板定义上下文中的任何内容都只能通过ADL获取。换句话说,正常的非限定查找仅在模板定义上下文中执行。

由于在定义func时未显示intermediate的声明,并且func不在与ns::type关联的命名空间中,因此代码格式不正确。< / p>

答案 1 :(得分:3)

海湾合作委员会是对的。 func只能通过ADL找到,因为它是一个不合格的依赖函数调用。 func在全局命名空间中声明,但ns::type的关联命名空间,只有ns(这就是您当前代码失败的原因)。当您通过直接调用intermediate(exit_node)内的func(exit_node)替换foo时,会通过正常的非限定查找找到它。