未使用using namespace at,为何at::zeros仍为函数重载候选?
LibTorch
zeros({}) 编译歧义问题解析 问题代码
#include <iostream> #include <torch/torch.h> using namespace torch; int main() { std::cout << zeros({}) << std::endl; }
编译报错信息
% g++ -lc10 -ltorch -ltorch_cpu test.cpp -o test.x test.cpp: In function ‘int main()’: test.cpp:5:23: error: call of overloaded ‘zeros(<brace-enclosed initializer list>)’ is ambiguous 5 | std::cout << zeros({}) << std::endl; | ~~~~~^~~~ In file included from /opt/links/include/ATen/Functions.h:1334, from /opt/links/include/ATen/ExpandUtils.h:4, from /opt/links/include/torch/csrc/autograd/input_metadata.h:3, from /opt/links/include/torch/csrc/autograd/function.h:7, from /opt/links/include/torch/csrc/autograd/custom_function.h:7, from /opt/links/include/torch/csrc/api/include/torch/autograd.h:5, from /opt/links/include/torch/csrc/api/include/torch/all.h:7, from /opt/links/include/torch/csrc/api/include/torch/torch.h:3, from test.cpp:2: /opt/links/include/ATen/ops/zeros.h:35:19: note: candidate: ‘at::Tensor at::zeros(IntArrayRef, c10::TensorOptions)’ 35 | inline at::Tensor zeros(at::IntArrayRef size, at::TensorOptions options={}) { | ^~~~~ In file included from /opt/links/include/torch/csrc/api/include/torch/types.h:7, from /opt/links/include/torch/csrc/api/include/torch/data/dataloader_options.h:4, from /opt/links/include/torch/csrc/api/include/torch/data/dataloader/base.h:3, from /opt/links/include/torch/csrc/api/include/torch/data/dataloader/stateful.h:4, from /opt/links/include/torch/csrc/api/include/torch/data/dataloader.h:3, from /opt/links/include/torch/csrc/api/include/torch/data.h:3, from /opt/links/include/torch/csrc/api/include/torch/all.h:9: /opt/links/include/torch/csrc/autograd/generated/variable_factories.h:565:19: note: candidate: ‘at::Tensor torch::zeros(at::IntArrayRef, c10::TensorOptions)’ 565 | inline at::Tensor zeros(at::IntArrayRef size, at::TensorOptions options = {}) { | ^~~~~
核心疑问
未使用using namespace at,为何at::zeros会被列为重载候选?
原因解析
这是C++**依赖参数查找(ADL,又称Koenig查找)**导致的:
- 调用
zeros({})时,编译器会将{}推导为at::IntArrayRef(该类型支持用初始化列表构造)。 - 根据ADL规则,编译器会自动在参数类型所属的命名空间(即
at)中查找同名函数,因此at::zeros会被纳入重载候选,和因using namespace torch而可见的torch::zeros产生歧义。
解决方法
以下几种方式均可消除歧义:
- 明确指定命名空间:直接限定调用
torch命名空间下的函数std::cout << torch::zeros({}) << std::endl; - 显式构造参数类型:将初始化列表包装为
at::IntArrayRef,避免ADL触发对at命名空间的查找std::cout << zeros(at::IntArrayRef{}) << std::endl;
内容的提问来源于stack exchange,提问作者Daniel Wagner
相关产品推荐
相关产品推荐

