Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于模板参数推断利用率的STL算法名称可解析或未定义_C++_C++11_Templates_Stl_Name Lookup - Fatal编程技术网

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());