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-list
<子>选择子>)
其中postfix-expression是一个id-expression,如果expression-list中的任何表达式是依赖于类型的表达式(14.6.2.2),或者id-的非限定id,则id-expression表示一个从属名称。 expression是一个template-id,其中任何模板参数都依赖于模板参数。 如果运算符的操作数是类型相关的表达式,则运算符也表示从属名称。 这些名称是未绑定的,在模板定义的上下文和实例化的上下文中都会查看模板实例化(14.6.4.1)。
此方案中的合规行为是什么?
答案 0 :(得分:1)
事实证明,由于C ++标准中的已知缺陷,此行为未指定:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html
DR 903.依赖于值的整数空指针常量
建议的解决方案是改变标准的措辞,只允许文字“0”作为空指针常量,但这正在审查中,因为它意味着破坏使用“假”的现有代码。
GCC似乎通过将'g'视为依赖名称来解决此问题。相比之下,Clang似乎认为依赖于值的表达式永远不能是空指针常量表达式。这两种方法都不是严格正确的,因为没有指定正确的行为。