C++ 基于模板参数推断利用率的STL算法名称可解析或未定义
鉴于此代码:C++ 基于模板参数推断利用率的STL算法名称可解析或未定义,c++,c++11,templates,stl,name-lookup,C++,C++11,Templates,Stl,Name Lookup,鉴于此代码: #include <algorithm> #include <vector> using std::vector; int main() { vector<int> intVec(100, 1); // no problem random_shuffle(intVec.begin(), intVec.end()); // no problem std::random_shuffle<vecto
#include <algorithm>
#include <vector>
using std::vector;
int main()
{
vector<int> intVec(100, 1);
// no problem
random_shuffle(intVec.begin(), intVec.end());
// no problem
std::random_shuffle<vector<int>::iterator>(intVec.begin(), intVec.end());
// random_shuffle undefined!
random_shuffle<vector<int>::iterator>(intVec.begin(), intVec.end());
}
#包括
#包括
使用std::vector;
int main()
{
向量intVec(100,1);
//没问题
随机洗牌(intVec.begin(),intVec.end());
//没问题
std::random_shuffle(intVec.begin(),intVec.end());
//随机洗牌未定义!
随机洗牌(intVec.begin(),intVec.end());
}
我意识到这段代码中的名称管理很糟糕。然而,一个较小的代码库启发了我的问题。随机随机洗牌是可解决的,没有std限定。如果限定并显式模板化,则不会再次出现问题。但是,如果没有std限定,并且没有显式模板参数(至少隐式正确),random_shuffle就会突然被取消定义。为什么?
VisualStudio 2017(我知道……如果这是MS ShanaigAs,只需这么说)
< P>函数调用表达式的非限定名称查找也可以考虑相关的命名空间,以便查找所引用的函数。此功能称为。正在搜索的一组相关名称空间包括函数调用参数类型本身的名称空间,以及函数调用参数的类模板类型的模板参数名称空间。换句话说,对于函数调用:foo(A::B<C::D>{});
std::random\u shuffle
是通过ADL找到的,ADL被触发的唯一原因是在VC++标准库实现中,std::vector::iterator
是在std
命名空间(std:\u vector\u iterator
)中定义的类类型,因此std
是执行名称查找的关联命名空间。然而,这并不能保证有效,因为向量迭代器也可以是指针,或者位于命名空间std
之外
在第二种情况下:
std::random_shuffle<vector<int>::iterator>(intVec.begin(), intVec.end());
std::random_shuffle(intVec.begin(),intVec.end());
编译器执行限定名称查找
在第三种情况下:
random_shuffle<vector<int>::iterator>(intVec.begin(), intVec.end());
random_shuffle(intVec.begin(),intVec.end());
以下项目符号适用:
:
8(…)当使用带有显式模板参数的函数模板时,调用没有
正确的语法形式,除非在调用点有一个函数模板,该模板的名称可见。
如果看不到这样的名称,则调用的语法格式不正确,依赖于参数的查找不适用
换句话说,f(a)
可以触发ADL,但是f(a)
——为函数调用显式提供模板参数,这正是您的情况——不能触发ADL
这个项目符号似乎只有在C++20之前才有效
random_shuffle<vector<int>::iterator>(intVec.begin(), intVec.end());