使用命名空间时,C模板函数无法使用g进行编译
以下代码编译得很好:(没有命名空间)
#include <vector> template <class T> void foo(const int & from,std::vector<T> & to) { for (int i = 0; i < 5; i++) { T bar; foo(from,bar); to.push_back(bar); } } struct Bar { int a; int b; }; struct Baz { std::vector<Bar> bars; }; void foo(const int & from,Bar & to) { to.a = from; to.b = from - 1; } void foo(const int & from,Baz & to) { foo(from,to.bars); } void fooTest() { int num = 10; Baz baz; foo(num,baz); } int main() { fooTest(); } 但是当我为Bar和Baz引入命名空间时,它无法编译. (带命名空间) #include <vector> template <class T> void foo(const int & from,bar); to.push_back(bar); } } // When I add this namespace,it fails to compile namespace BarBar { struct Bar { int a; int b; }; struct Baz { std::vector<Bar> bars; }; } void foo(const int & from,BarBar::Bar & to) { to.a = from; to.b = from - 1; } void foo(const int & from,BarBar::Baz & to) { foo(from,to.bars); } void fooTest() { int num = 10; BarBar::Baz baz; foo(num,baz); } int main() { fooTest(); } 它显示错误: with_namespace.cpp: In instantiation of ‘void foo(const int&,std::vector<T>&) [with T = BarBar::Bar]’: with_namespace.cpp:37:22: required from here with_namespace.cpp:9:12: error: no matching function for call to ‘foo(const int&,BarBar::Bar&)’ foo(from,bar); ^ with_namespace.cpp:4:6: note: candidate: template<class T> void foo(const int&,std::vector<T>&) void foo(const int & from,std::vector<T> & to) ^ with_namespace.cpp:4:6: note: template argument deduction/substitution failed: with_namespace.cpp:9:12: note: ‘BarBar::Bar’ is not derived from ‘std::vector<T>’ foo(from,bar); ^ 另请注意,使用MSVC时,带命名空间的代码编译得很好.为什么编译器在使用命名空间时找不到定义? 我使用以下版本:g(Ubuntu 5.4.0-6ubuntu1~16.04.9)5.4.0 20160609 更新: #include <vector> template <class T> void foo(const int & from,bar); to.push_back(bar); } } namespace BarBar { struct Bar { int a; int b; }; struct Baz { std::vector<Bar> bars; }; }; // Put them in the same namespace as Bar so that the templated foo find this function namespace BarBar { using ::foo; // We are going to use templated foo in the latter functions void foo(const int & from,BarBar::Bar & to) { to.a = from; to.b = from - 1; } void foo(const int & from,BarBar::Baz & to) { foo(from,to.bars); } } void fooTest() { int num = 10; BarBar::Baz baz; BarBar::foo(num,baz); } int main() { fooTest(); } 解决方法
在代码中:
template <class T> void foo(const int & from,std::vector<T> & to) { T bar; foo(from,bar); 名称栏依赖于类型,因为其类型取决于模板参数.此外,名称foo(在foo(from,bar)中)是一个从属名称,因为其中一个函数调用参数是类型相关的. (C 17 [temp.dep] / 1). 依赖名称的名称查找工作方式如下(C 17 [temp.dep.res] / 1):
第二个项目符号点称为ADL(依赖于参数的查找). 在你的第二个代码中,查找依赖foo什么都找不到: >在模板的位置没有其他可见的定义 在第一个代码中,查找依赖的foo:int和:: Bar的关联命名空间是:全局命名空间.全局命名空间中有:: foo,因此ADL可以找到它. 要修复第二个代码,您应该将后面带有BarBar ::参数的foo定义移到名称空间BarBar中. (在这种情况下,您还需要在第37行使用:: foo来查找模板foo). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |