- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
如果我对 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
进行不合格调用时,我们有两种不同的查找:
常规不合格查找 - 由于您有 using namespace std;
,最终会执行与上述完全相同的操作- 它会找到 std::tuple_cat
并且能够最终确定“正确”答案(对于允许以 tuple<void>
开头的某些权利定义)。
参数依赖查找。 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/
我试图了解 declval() 之间的区别和 declval() ?有没有示例 T&可以在 T 时使用不能吗? #include #include struct X { X() = delet
用std::declval不是更好吗?声明形式: template T declval(); // (1) 然后是当前的: template T && declval(); // (2) std::c
我想弄清楚如何在 is_assignable 的实现中解释 declval() = declval()。 declval 将类型转换为引用。鉴于此,我将表达式转换为以下四种可能性之一: _Dest&&
我正在尝试使用 detector我是根据std::experiment::is_detected_v写的检查类型是否可分配。然而std::declval() = std::declval()无效且只有
根据 is_destructible 的定义( http://eel.is/c++draft/meta.unary.prop#lib:is_destructible ), is_destructib
标准库实用程序 declval是defined作为: template add_rvalue_reference_t declval() noexcept; 在 C++11 中引入右值引用似乎是个好主
我想尝试编写一个模板包装器来检查类是否具有成员函数。为此,有必要使用 std::declval template struct has_member().push_back())>>:std::tru
以下代码在模板参数T时编译失败是基本类型,例如 int (在 gcc 4.8 上)。这是符合标准的行为吗?我对std::declval的理解是它总是解析为 T&&或 T& . template vo
引用以下Proposing Standard Library Support for the C++ Detection Idiom中的例子: // primary template handles
假设我有一个将要专门化的模板化函数,所以我真的不关心基本实现。我可以做这样的事情吗: template T dummy() { assert(false); return declv
一个最小的例子,展示了两种获取迭代器类型的方法,我天真地希望得到与结果相同的类型: template struct foo { using iterator = decltype(std::
有人可以解释一下 std::declval 是如何工作的吗?我在 gcc headers/type_traits(第 2248-2262 行)中找到了这个实现,它是(清理了一下以提高可读性): tem
我在玩 GCC (4.9.2) abi::__cxa_demangle 时遇到了无法分解特定符号名称的情况。 那个符号是: _ZNK12DebugWrapperIR5TestClsE5getIdIIE
当您使用模板和 decltype 时你经常需要某种类型的实例,即使你没有任何时间。在这种情况下,std::declval()非常有用。这将创建一个 T 类型的虚构实例. 有没有类似的概念?即一个函数,
查看libstdc++源码,发现如下declval实现: template _Up __declval(int); // (1) template _Tp __declval(long); // (
我正在编写一些元函数,并且我有想法使用 C++17 的 if constexpr 结合推导的返回类型来编写它们。这是一个例子: #include #include #include templa
cppreference web site引入 declval : Note that because no definition exists for declval, it can only be
std::declval是一个编译时实用程序,用于构造表达式以确定其类型。它是这样定义的: template typename std::add_rvalue_reference::type decl
据我所知,我无法声明对 void 的右值引用. 例如,以下代码格式错误: void f(void &&v) { } 来自 [20.2.6/1] (函数模板 declval)我们有一个 declval
std::declval是一个编译时实用程序,用于构造表达式以确定其类型。它是这样定义的: template typename std::add_rvalue_reference::type decl
我是一名优秀的程序员,十分优秀!