9

当我在寻找有关我在源代码中遇到的编译问题的线索时,我遇到了这个与函数查找相关的错误报告(针对 Mozilla 的 JavaScript 引擎源代码) 。引用错误报告:

TypedArrayTemplate (显然)是一个模板,它引用了 INT_TO_JSVAL,一个静态内联函数,没有前缀“::”。这会破坏 xlC,因为它无法解析 INT_TO_JSVAL。如果在模板参数的上下文中找不到非限定名称,则该标准不要求考虑静态。g++ 做这个后备,xlC 没有。

来自编译器的信息性消息:

(I) Static declarations are not considered for a function call if the function is not qualified.

在我的情况下,失败的代码类似于:

namespace N
{

static bool foo (std::string const &);

template <typename T>
void bar (T const &, std::string const & s)
{
    // expected unqualified call to N::foo()
    foo (s);
}

void baz (std::string const & s)
{
    bar (s);
}

} // namespace N

xlC 实现的行为真的正确吗?2003 年或 2011 年的标准在哪里谈论这个?

4

2 回答 2

9

在 C++11 之前,这是正确的行为:模板中使用的名称的非限定名称解析被定义为仅查找具有外部链接的函数。

C++03 第 14.6.4.2 节候选函数 [temp.dep.candidate] 第 1 段:

对于依赖于模板参数的函数调用,如果函数名称是非限定 ID 但不是模板 ID,则使用通常的查找规则(3.4.1、3.4.2)找到候选函数,但以下情况除外:

  • 对于使用非限定名称查找 (3.4.1) 的查找部分,仅找到具有来自模板定义上下文的外部链接的函数声明。

  • 对于使用关联命名空间 (3.4.2) 的查找部分,仅找到在模板定义上下文或模板实例化上下文中找到的具有外部链接的函数声明。

在 C++11 中更改为:

对于依赖于模板参数的函数调用,使用通常的查找规则(3.4.1、3.4.2、3.4.3)找到候选函数,除了:

  • 对于使用非限定名称查找 (3.4.1) 或限定名称查找 (3.4.3) 的查找部分,只能找到来自模板定义上下文的函数声明。

  • 对于使用关联命名空间 (3.4.2) 的查找部分,仅找到在模板定义上下文或模板实例化上下文中找到的函数声明。

于 2013-07-15T19:56:23.990 回答
4

V12.1 的编译器默认具有新的行为。

如果您使用的是早期版本的 xlC 编译器,请使用选项-qdebug=KeepUnqualifiedStaticCandidate

于 2013-07-16T13:28:06.137 回答