问题标签 [declval]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
716 浏览

c++ - 了解 declval 优化实现

查看 libstdc++ 源代码,我发现了以下declval实现:

这个实现由 Eric Niebler 作为编译时优化提出的:他解释说重载解析比模板实例化更快。

但是,我无法理解它是如何工作的。具体来说:

  1. 在(1)中,为什么使用_Up比仅仅返回更好_Tp&&
  2. 似乎从未使用过重载(2)。为什么需要它?

这一切如何防止模板实例化,而不是最天真的实现:

0 投票
0 回答
86 浏览

c++ - 如何检索可变参数模板参数的类型?

我找不到一种方法来定义这样的类型:

我的问题是编译器不允许我在上下文中编写它:

有没有办法用可变参数模板化参数定义可变参数模板成员函数的类型?

我正在使用 c++17。

提前非常感谢。

0 投票
1 回答
274 浏览

c++ - std::declval vs crtp,无法从不完整类型推断方法返回类型

我正在尝试做这样的事情(在 c++11 中):

失败了

如何为bar::fooin的返回类型声明别名base?不可能吗?

这个问题似乎是相当相关的:对于不完整类型的呼叫运算符的 decltype 的特殊行为,尽管我无法将那里给出的答案应用于我的案例。

0 投票
1 回答
245 浏览

c++ - 对于什么 T `std::declval()` 没有匹配函数?

我惊讶地发现,对于某些T,decltype(std::declval<T>())是不合法的:

cppreference似乎并未表明此错误是预期的。

还有其他declval<T>不能使用的类型吗?规范在哪里定义这些?

0 投票
2 回答
628 浏览

c++ - T 是否必须是完整的类型才能在 `std::declval 中使用`?

考虑这个例子(来自这里):

在 gcc9.2 上编译没有错误,但 gcc7.2 和 clang 10.0.0 抱怨B不完整。Clangs错误是:

0 投票
3 回答
51 浏览

c++ - 编译器推断模板参数

有没有办法在 A (或其他地方)的声明中提示编译器 T 应该自动解析为传递给构造函数的类型?

(理想情况下是 c++11,但很高兴听到更少的旧版本)

0 投票
2 回答
2404 浏览

c++ - 为什么 libstdc++-v3 中 declval 的实现看起来那么复杂?

下面的代码来自 libstdc++-v3 std::type_traits,它是一个实现std::declval

但我想我可以declval简单地实现:

这是我的测试代码:

构建和运行命令是:

  1. 为什么 libstdc++-v3 中的实现看起来如此复杂?
  2. 第一个片段中的模板 1 有什么作用?
  3. 为什么__declval需要一个参数(int/ long)?
  4. 为什么模板 1 ( int) 和模板 2 ( long) 有不同的参数类型?
  5. 我的简单实现有什么问题吗?
0 投票
1 回答
122 浏览

c++ - 将 declval 与引用类型一起使用

我看到一些代码示例,其中用于实例化std::declval模板函数的类型被指定为引用类型,而不仅仅是一个类型,如下所示:

相对于:

T某种类型在哪里。我错过了为什么选择引用符号而不是普通类型的微妙之处。有人可以向我解释一下吗?

我知道这std::declval扩展为,typename std::add_rvalue_reference<T>::type但我仍然想念为什么人们会通过引用类型而不是普通类型本身来实例化后者的原因。

0 投票
2 回答
100 浏览

c++ - 由于保证复制省略,std::declval 是否已过时?

标准库实用程序declval定义

如果您考虑在C++11中引入该语言时在此处添加右值引用似乎是一个好主意:返回值涉及一个临时值,该值随后被移出。现在C++17引入了保证复制省略,这不再适用。正如cppref所说:

C++17 prvalues 和 temporaries 的核心语言规范与早期的 C++ 修订版根本不同:不再有一个临时的可以复制/移动。描述 C++17 机制的另一种方式是“未实现的值传递”:纯右值被返回并使用,而无需实现临时值。

这对根据declval. 看看这个例子(在godbolt.org上查看):

这里我们有一个不可移动的类。由于保证复制省略,它可以从函数返回,然后在本地实现test()。然而,is_construtible类型特征表明这是不可能的,因为它是根据以下定义declval

is_­constructible<T, Args...>当且仅当以下变量定义对于某个发明的变量是格式良好的时,模板特化的谓词条件 才会被满足t
T t(declval<Args>()...);

因此,在我们的示例中,类型特征说明 ifClass可以从返回的假设函数构造Class&&test()尽管命名表明确实如此,但任何当前类型特征都无法预测是否允许输入行is_constructible

这意味着,在保证复制省略实际上可以挽救局面的所有情况下,is_constructible通过告诉我们“它可以在 C++11中构造吗?”的答案来误导我们。

这不限于is_constructible. 用(在godbolt.org上查看)扩展上面的例子

这表明is_invocable同样受到影响。

最直接的解决方案是更改declval

这是 C++17(及后续,即 C++20)标准中的缺陷吗?还是我错过了为什么这些declval和 规范仍然是我们可以拥有的最佳解决方案?is_constructibleis_invocable

0 投票
0 回答
87 浏览

c++ - 为什么不是 std::declval() 当 std::declval 时为左值() 是?

这两行中的第一行无法编译,第二行在 MSVC 2017 中编译:

错误消息是“表达式必须是可修改的左值”。

我知道这declval会增加一个右值引用。因此,在第一行中,编译器认为(不是吗?)std::declval<int>()作为右值引用的结果。在第二行中std::declval<int&>(),由于折叠规则,编译器将结果视为左值引用。

为什么右值引用不是可修改的左值,而左值引用是?