c++ - 什么时候应该对具有依赖空指针常量表达式参数的非限定函数调用进行名称查找?

标签 c++ templates null expression language-lawyer

Clang 3.0 拒绝以下代码,提示找不到g(unsigned long)。 GCC 4.8 接受它没有错误。

void g(int*);

void f()
{
    g(sizeof(int) - sizeof(int)); // ok, evaluates to 0
}

template<typename T>
struct A
{
    void f()
    {
        g(sizeof(T) - sizeof(T)); // error: no matching function
    }
};

我对该标准的阅读表明“g”不是从属名称,应该像 clang 那样立即查找和绑定(bind)。即便如此,标准指定的行为似乎是错误的,因为 g 否则会在实例化时正确绑定(bind)。

[temp.dep]
[...] In an expression of the form:
postfix-expression ( expression-listopt)
where the postfix-expression is an id-expression, the id-expression denotes a dependent name if any of the expressions in the expression-list is a type-dependent expression (14.6.2.2) or if the unqualified-id of the id-expression is a template-id in which any of the template arguments depends on a template parameter. If an operand of an operator is a type-dependent expression, the operator also denotes a dependent name. Such names are unbound and are looked up at the point of the template instantiation (14.6.4.1) in both the context of the template definition and the context of the point of instantiation.

这种情况下的合规行为是什么?

最佳答案

事实证明,由于 C++ 标准中的已知缺陷,此行为未指定:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html

DR 903. Value-dependent integral null pointer constants

提议的解决方案是更改标准的措辞,以仅允许文字“0”作为空指针常量,但这正在审查中,因为这将意味着破坏使用“false”的现有代码。

GCC 似乎通过将“g”视为从属名称来解决此问题。相反,Clang 似乎规定依赖于值的表达式永远不能是空指针常量表达式。这两种方法都不是严格正确的,因为正确的行为是未指定的。

关于c++ - 什么时候应该对具有依赖空指针常量表达式参数的非限定函数调用进行名称查找?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18048144/

相关文章:

c++ - 使用不同功能的队列中的打印元素不会在_start程序中全局清空队列。还有更多解释吗?

在 main() 中访问类成员时出现 C++ 段错误

c++ - 传递一个带有N个参数的模板,作为模板参数,用N-1个参数指定

go - 向 chan 发送了一个 nil 指针,但收到了 "non-nil"

c++ - 为我的类(class)重载 <<

c++ - C++中类的内存是如何处理的?

c++ - CRTP + 特征类 : "no type named..."

c++ - 尝试使用模板创建类的新实例,出现意外错误

c# - Type.getType() 找不到类

C# 对象失去它的引用并变为空