- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
考虑以下代码:
#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/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!