gpt4 book ai didi

c++ - 基于模板参数推导利用的 STL 算法名称可解析或未定义

转载 作者:行者123 更新时间:2023-11-30 03:24:08 24 4
gpt4 key购买 nike

给定这段代码:

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

我意识到这段代码中的名称管理很糟糕。然而,一个不太小的代码库激发了我的问题。 random_shuffle 是可解析的,没有 std 资格。如果合格且明确模板化,则不再有问题。但是,如果没有 std 限定和显式模板参数(至少隐式正确),则 random_shuffle 突然未定义。为什么?

Visual Studio 2017(我知道...如果这是 MS 恶作剧,就这么说)

最佳答案

函数调用表达式的非限定名称查找也可以考虑关联的命名空间,以便找到引用的函数。此功能称为 Argument-dependent lookup .正在搜索的关联 namespace 集包括函数调用参数本身类型的 namespace ,以及函数调用参数的类模板类型的模板参数的 namespace 。换句话说,对于函数调用:

foo(A::B<C::D>{});

关联的命名空间集包括namespace Anamespace C , 并检查两者以找到函数声明 foo .

第一种情况:

random_shuffle(intVec.begin(), intVec.end());

std::random_shuffle通过 ADL 找到,仅因为在 VC++ 标准库实现中才被触发 std::vector<int>::iteratorstd 中定义的类类型命名空间( std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>> ),因此 std是一个关联的 namespace ,用于执行名称查找。然而,这并不能保证有效,因为 vector 迭代器也可以是指针,或者位于 namespace std 之外。 .

第二种情况:

std::random_shuffle<vector<int>::iterator>(intVec.begin(), intVec.end());

编译器执行限定名称查找。

第三种情况:

random_shuffle<vector<int>::iterator>(intVec.begin(), intVec.end());

以下要点适用:

[temp.arg.explicit]/p8 :

8 (...) when a function template with explicit template arguments is used, the call does not have the correct syntactic form unless there is a function template with that name visible at the point of the call. If no such name is visible, the call is not syntactically well-formed and argument-dependent lookup does not apply.

换句话说,f(a)可以触发 ADL,但是 f<B>(a) -- 为函数调用显式提供模板参数,这正是您的情况 -- 不能。

这条要点似乎只在 C++20 之前有效。

关于c++ - 基于模板参数推导利用的 STL 算法名称可解析或未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49963749/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com