gpt4 book ai didi

c++ - 模板参数包如何同时具有显式参数和推导参数?

转载 作者:搜寻专家 更新时间:2023-10-31 01:28:47 25 4
gpt4 key购买 nike

g++、clang++ 和 MSVC(2018 年之前)全部 accept以下 C++17 代码,导致输出“unsigned int”然后是“int”:

#include <iostream>

void print_type(int) { std::cout << "int\n"; }
void print_type(unsigned int) { std::cout << "unsigned int\n"; }

template <typename ...T>
void print_types(T ...args)
{
(print_type(args),...);
}

int main()
{
print_types<unsigned int>(1, 1);
}

我同意这应该以这种方式工作,但我很难在标准中找到关于原因和具体方式的描述。

首先是 [temp.deduct]/2 描述了在进行剩余的模板参数推导之前显式模板参数的处理:

[T]he following steps are performed when evaluating an explicitly specified template argument list with respect to a given function template:

  • ... There must not be more arguments than there are parameters unless at least one parameter is a template parameter pack, and there shall be an argument for each non-pack parameter....

  • The specified template argument values are substituted for the corresponding template parameters as specified below.

例子中,unsigned int当然是一个“指定的模板参数值”。但是如果它的“相应的模板参数” T 现在被替换,很难看出它以后如何成为一个更长的类型列表。

对于模板参数推导过程,有[temp.deduct.call]/1:

For a function parameter pack that occurs at the end of the parameter-declaration-list, deduction is performed for each remaining argument of the call, taking the type P of the declarator-id of the function parameter pack as the corresponding function template parameter type. Each deduction deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack.

我在这里使用“调用的剩余参数”是指与不是最终函数参数包的函数参数相对应的参数之后的参数。但这意味着在我的示例中,第一个函数参数 1 用于推导 T=int。这种推导是否真的发生了,但随后被显式模板参数中的 T=unsigned int 丢弃/覆盖?

或者“调用的剩余参数”应该是指在不对应于最终函数参数包的函数参数之后以及在任何对应于从显式模板参数生成的参数类型之后的函数参数;并且“由函数参数包扩展的模板参数包中的后续位置”应该是指任何由显式模板参数填充之后的顺序位置,但这远非明确。如果是这样,还有一个与函数参数包关联的参数类型列表,但它仍然是一个函数参数包,这也令人困惑。

[给出预期行为的另一种可能实现是:当一个或多个显式模板参数 A_1, ..., A_k 对应于模板参数包 P,再发明一个同类的模板参数包More_P,将P的每一次展开都替换为模板参数列表{A_1, ..., A_k, More_P...}。然后More_P可以像任何其他模板参数包一样推导出来。如果 More_P 从未被推导,则在评估语义之前用一个空列表替换它的所有扩展,就像对所有其他推导的替换一样。但在标准中这种解释的理由更少。]

我是否错过了标准中更好地描述显式模板参数和推导模板参数如何协同工作以形成一个模板参数包的单个列表的内容?

最佳答案

[temp.arg.explicit]/8 :

Template argument deduction can extend the sequence of template arguments corresponding to a template parameter pack, even when the sequence contains explicitly specified template arguments. [ Example:

template<class ... Types> void f(Types ... values);

void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}

— end example ]

关于c++ - 模板参数包如何同时具有显式参数和推导参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51340237/

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