为什么依赖于参数的查找不适用于 std::make_tuple?[复制]

Why doesn't argument-dependent lookup work for std::make_tuple? [duplicate]

提问人:H.v.M. 提问时间:9/14/2023 更新时间:9/14/2023 访问量:75

问:

写作而不是在这里工作,因为依赖于参数的查找:tiestd::tie

std::tuple<int, std::string> tup = std::make_tuple<int, std::string>(1, "a");
int i;
std::string str;
tie(i, str) = tup;

但为什么需要?make_tuplestd::

C++ 命名空间 argument-dependent-lookup

评论

1赞 wohlstad 9/14/2023
若要使 ADL 正常工作,需要命名空间中的参数之一。这将起作用:.std::tuple<int, std::string> tup = make_tuple<int, std::string>(1, std::string{ "a" });
1赞 康桓瑋 9/14/2023
由于 nor 都不在命名空间下,请尝试 .1"a"stdmake_tuple(1, std::string("a"))
0赞 molbdnilo 9/14/2023
它们是不一样的; 是 ,而 是 。"a"const char[2]strstd::string
1赞 Jarod42 9/14/2023
@wohlstad:需要 C++20 来执行 ADL(除非 OP 还在全局命名空间中定义了一些)。<..>make_tuple<..>
0赞 wohlstad 9/14/2023
@Jarod42好点子。我会把它添加到我的答案中。

答:

4赞 wohlstad 9/14/2023 #1

若要使 ADL(依赖于参数的查找)正常工作,需要命名空间中的参数之一。std

在你对 ( is a ) 的调用中就是这种情况,但在对 (neigher nor are) 的调用中不是这种情况。tiestrstd::stringmake_tuple1"a"

您可以通过提供如下内容来使用 ADL:std::string

//-----------------------------------------------------------------vvvvvvvvvvv--------
std::tuple<int, std::string> tup = make_tuple<int, std::string>(1, std::string{ "a" });

注意:
上面的代码尝试最接近您的版本,需要 c++20(其中显式模板参数不会阻止 ADL)。
但是 - 这个版本也较短,适用于早期的 c++ 版本:

std::tuple<int, std::string> tup = make_tuple(1, std::string{ "a" });

评论

0赞 H.v.M. 9/14/2023
在 ADL 中不使用函数的类型参数有什么特殊原因吗?
2赞 wohlstad 9/14/2023
这就是它的指定方式(您可以在我发布的链接中看到)。我不知道这背后的原因。这是一篇不错的文章——你可以看看,以防我错过了一些关于理性的东西。看起来最初 ADL 旨在解决一个特定的、更狭窄的问题。