C++名称解析困境
C++ name resolution woes
我有一个自定义类,我想提供sin
函数的模板化版本 - 我已经在我的最小可验证重新定义中将其称为foo
。由于其他地方的一些模板元编程,我的sin
函数与普通sin
函数具有相同的名称是有利的,因为它正在执行相同的工作,只是在不同的类型上。
但是,以下内容不会编译:
#include <cmath>
#include <iostream>
#include <cstdlib>
namespace test
{
template <std::size_t size>
class foo
{
};
template <std::size_t size>
void sin(const foo<size>& f)
{
}
template <class T>
void bar(const T& x)
{
using namespace ::std;
sin(x);
}
}
int main()
{
test::bar(0.5);
std::cout << "Done...";
std::getchar();
return EXIT_SUCCESS;
}
我收到以下编译器错误:
..testproblem.cpp(23,3): error: no matching function for call to 'sin'
sin(x);
^~~
..testproblem.cpp(29,8): note: in instantiation of function template specialization 'test::bar<double>' requested here
test::bar(0.5);
^
..testproblem.cpp(14,7): note: candidate template ignored: could not match 'foo<size>' against 'const double'
void sin(const foo<size>& f)
^
1 error generated.
我对此感到惊讶。有没有办法让bar
编译而不使用模板元编程技巧来创建多个版本的bar
?
在 Clang 9 和 MSVC 2019 中失败。
using指令和 using 声明之间存在差异。using namespace ::std;
是一个使用指令。就非限定名称查找而言,如果使用在名称查找点找不到名称,则 using 指令基本上只是转发名称查找以搜索命名空间::std
到达包含两者的最近命名空间,包含指令的命名空间和指令 [namespace.udir]/2 指定的命名空间。在您的情况下,这意味着名称查找必须先到达全局命名空间,然后才能找到::std::sin
。但是,名称查找将首先到达命名空间test
,其中包含一个名为sin
的函数,然后停止,因为它已经找到了它要查找的内容 [basic.lookup.unqual]/1。你想要的是一个 using 声明:
template <class T>
void bar(const T& x)
{
using std::sin;
sin(x);
}
与 using 指令相反,using 声明直接将声明的名称引入 using 声明所在的范围 [namespace.udecl]/1,这意味着将立即找到std::sin
。现在,这意味着正常的非限定名称查找将不再在 using 声明后的块范围内找到test::sin
。但是,由于依赖于参数的名称查找 [basic.lookup.argdep],如果test::foo
的实例,将找到test::sin
并再次设置部分重载T
...
这是一个基于(a(评论和(b(评论中链接的答案的"快速修复"。bar
函数的最小版本是:
void bar()
{
::sin(0.5); // Without "::" your templated "test::sin" hides the global namespace
// version - which is here referenced EXPLICITLY.
}
- C++名称解析困境
- C++简单函数困境
- 双重选择对数组进行排序 - 诚实地陷入困境
- 循环时我如何摆脱困境
- B/B 树的实现与使班级成为另一个班级困境的朋友有关
- C++:关于囚徒困境申请的建议
- 为什么我会陷入困境?[C ]
- C++和CRTP模式的实现与编译器困境
- C++的记忆分配困境
- 递归下降解析器,变量与自身的初始化,困境
- C++ 演练困境:
- C++指针的困境
- OpenGL纹理加载困境
- C++tron AI陷入了自己的困境
- C++中的指针 - 初学者的困境
- 字符串长度的困境
- C/C++ API 设计困境
- VS2012使用3D模型的困境
- 创建一个体素系统并陷入困境,发现自己需要关于如何实现它的信息
- 正则表达式的困境