gpt4 book ai didi

c++ - 使用 std::tuple_cat 模板实例化 decltype 和 declval

转载 作者:太空狗 更新时间:2023-10-29 20:33:23 25 4
gpt4 key购买 nike

如果我对 std::tuple_cat 进行完整、合格的调用,则以下代码将使用 MSVC、GCC 和 Clang 进行编译.但是如果我对 tuple_cat 进行不合格的调用,它不会在这些编译器中的任何一个上编译。 ... 即使我正在做 using namespace std; !

如果我不合格地调用该函数,所有三个编译器都会找到正确的函数 - 但会提示 std::tuple<void> 的实例化无效.

为什么这很重要?这应该没什么区别吗?

#include <tuple>

auto Test() {
using A = std::tuple<void>;
using B = std::tuple<void>;

using namespace std;
using AB = decltype(
#ifdef QUALIFIED
std::
#endif
tuple_cat(std::declval<A>(), std::declval<B>())
);

AB* ptr = nullptr;
return ptr;
}

参见 demo .

最佳答案

实例化 tuple<void>格式错误,但只是命名它不是。这里的区别恰好归结为一种情况需要完全实例化,另一种情况只需要查看模板参数。

当您对 std::tuple_cat 进行完全限定调用时,名称查找只找到名为 tuple_cat 的内容在命名空间内 std .这将是一些函数模板,需要一堆 tuple s 并弄清楚如何连接他们的论点。令人惊讶的是,弄清楚此函数模板的返回类型的任何部分实际上都不需要在任何地方实例化。

但是当您对 tuple_cat 进行不合格调用时,我们有两种不同的查找:

  1. 常规不合格查找 - 由于您有 using namespace std;,最终会执行与上述完全相同的操作- 它会找到 std::tuple_cat并且能够最终确定“正确”答案(对于允许以 tuple<void> 开头的某些权利定义)。

  2. 参数依赖查找。 ADL 要求我们查看所有关联的命名空间和来 self 们参数的其他函数。其中包括“隐藏的 friend ”- friend在类的主体中定义的函数。要知道是否有任何隐藏的 friend ,我们需要完全实例化这些类型 - 正是在这一点上,我们遇到了错误,一切都崩溃了。

这个 ADL 步骤必须发生 - 我们不知道 std::tuple_cat是唯一tuple_cat直到我们执行了那一步。


什么是隐藏 friend 的例子:

template <typename T>
int foo(T) { return 42; }

template <typename T>
struct A {
friend bool foo(A) { return true; } // this is a hidden friend
};

using R = decltype(foo(declval<A<int>>()));

为了判断什么R就是,我们需要实例化A<int>查看它是否有任何隐藏的 friend - 它有,这就是我们如何获得 bool对于 R .如果我们对 foo 进行了合格的调用,我们会得到 int .

关于c++ - 使用 std::tuple_cat 模板实例化 decltype 和 declval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55678259/

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