c++ - 在std::exchange中,为什么第二个模板参数默认了?

标签 c++ templates stl c++14 default-arguments

C++14 标准为 std::exchange 指定以下声明:

template <class T, class U = T>
T std::exchange(T& obj, U&& new_value);

我想知道为什么 U 默认为 T,因为 U 可以通过 new_value 找到。在什么情况下,这会导致不同的结果:

template <class T, class U>
T std::exchange(T& obj, U&& new_value);

最佳答案

std::exchange建议于 N3511 没有默认模板参数,后来 N3608使用默认模板参数。请注意,在 N3608 中提供了以下推理:

Giving the second template argument a default value fixes the following two cases:

DefaultConstructible x = ...;
if (exchange(x, {})) { ... }

int (*fp)(int);
int f(int);
double f(double);
/*...*/ exchange(fp, &f) /*...*/

第一个例子的用处当然是一个无类型的临时{}将推导出为 T .第二个例子涉及更多:

14.8.2 Template argument deduction [temp.deduct]

5 The resulting substituted and adjusted function type is used as the type of the function template for template argument deduction. If a template argument has not been deduced and its corresponding template parameter has a default argument, the template argument is determined by substituting the template arguments determined for preceding template parameters into the default argument. If the substitution results in an invalid type, as described above, type deduction fails.

14.8.2.5 Deducing template arguments from a type [temp.deduct.type]

4 In most cases, the types, templates, and non-type values that are used to compose P participate in template argument deduction. That is, they may be used to determine the value of a template argument, and the value so determined must be consistent with the values determined elsewhere. In certain contexts, however, the value does not participate in type deduction, but instead uses the values of template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.

5 The non-deduced contexts are:

(5.5) — A function parameter for which argument deduction cannot be done because the associated function argument is a function, or a set of overloaded functions (13.4), and one or more of the following apply:

(5.5.1) — more than one function matches the function parameter type (resulting in an ambiguous deduction)

在第二个例子中,模板参数U仅在非推导上下文中使用,因为两个重载 f(int)f(double)两者都可以匹配到 U .因此,不会进行参数推导,并且 U成为提供的默认值 T (在本例中为 int (*)(int),因此选择了 f(int))。

此外,正如@VladfromMoscow 所解释的,具有默认参数允许在传递std::exchange<T> 时使用更短的代码。 (例如标准算法)。

关于c++ - 在std::exchange中,为什么第二个模板参数默认了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34876969/

相关文章:

php - Laravel 5 获取 View 名称

c++ - 虚成员函数定义可以出现在类模板之外吗?

c++ - 使用带有冗余信息的键字符串的 map ?

c++ - 踩踏无法在静态 map 容器中插入值

c++ - 使用 C++ 从文件读取到单个内存块

c++ - 循环终止时无法获得输入

c# - 访问位图的字节数组

c++ - 为什么使用常量表达式作为模板参数?

c++ - 如何扩展这个 C++11 事件系统来处理多个参数?

c++ - 输入迭代器的示例,其中 `end()` 实际上表示最后一次?