2

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 似乎做的那样立即查找和绑定。即便如此,标准指定的行为似乎是错误的,因为g否则会在实例化时正确绑定。

[temp.dep]
[...] 在以下形式的表达式中:
postfix-expression ( expression-listopt)
其中后缀表达式是 id 表达式,如果表达式列表中的任何表达式是类型,则 id 表达式表示依赖名称-dependent 表达式 (14.6.2.2) 或者如果 id-expression 的 unqualified-id 是模板 ID,其中任何模板参数都依赖于模板参数。如果运算符的操作数是依赖于类型的表达式,则该运算符也表示依赖名称。此类名称是未绑定的,并且在模板定义的上下文和实例化点的上下文中都在模板实例化点 (14.6.4.1) 处查找。

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

4

1 回答 1

1

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

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

DR 903. 与值相关的整数空指针常量

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

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

于 2013-08-04T22:24:54.627 回答