gpt4 book ai didi

c++ - 哪个编译器对于以下重载/特化行为是正确的?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:21:32 24 4
gpt4 key购买 nike

考虑以下代码:

#include <stdio.h>

namespace Foo {
template <typename T>
void foo(T *, int) { puts("T"); }

template <typename T>
struct foo_fun {
static void fun() { foo((T *)0, 0); };
};
}

namespace Foo {
void foo(int *, int) { puts("int"); }
}

using namespace Foo;

int main() {
foo_fun<int> fun;
fun.fun();
}

预期的输出是什么? “T”还是整数?

一个编译器(Apple 的 Xcode 3.1.2 中的 gcc 4.0.1)输出“int”,另外两个编译器(gcc 4.1.2 和 4.1.3)输出“T”。

如果我在 foo(T *, int) 版本之前移动 foo(int *, int) 声明/定义,所有输出“int”。当前标准是否定义了这种情况下的重载/特化顺序?

最佳答案

第二个 void foo(... 是一个重载(而不是特化),它在 foo_fun::fun 的定义中不可见,所以它不会'在模板定义的上下文中找不到。因为 T* 是依赖类型,表达式 foo((T*)0, 0) 将延迟到模板实例化时间,并且还将考虑实例化的上下文。但是,标准的 14.6.4.2 说如果函数名称是 unqualified-id但不是 template-id 那么对于非 ADL 查找,仅考虑在模板定义点可见的函数。Foo 命名空间中没有函数参数,因此没有参数相关的查找发生,因此 foo 的模板版本被调用而不是非模板重载。

非常感谢 litb 对这个答案的更正。

如果如下所示将其设为特化,那么由于在模板实例化时选择了特化,因此只要相关特化在首次为 实例化函数模板时可见,就可以调用该特化整数

namespace Foo {
template<>
void foo<int>(int *, int) { puts("int"); }
}

当前标准的第 14 章,但可读性不是很好 :)

编辑:如果我必须选择标准中最相关的部分,它可能是 14.6 [temp.res] 第 9 段。(略有缩写)如果名称不依赖于 模板参数,该名称的声明应在该名称出现在模板定义中的位置范围内;该名称绑定(bind)到此时找到的声明,并且此绑定(bind)不受实例化时可见的声明的影响。

编辑,编辑:但您还需要考虑 14.6.4.2 [temp.dep.candidate]。由于所有的相互依赖性,尝试引用标准是非常困难和危险的,这个答案就是一个很好的例子。

关于c++ - 哪个编译器对于以下重载/特化行为是正确的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/403929/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com