gpt4 book ai didi

c++ - 以可变类模板作为函数调用参数的函数模板参数推导

转载 作者:行者123 更新时间:2023-11-30 03:47:58 24 4
gpt4 key购买 nike

所有例子都来自herehere .

具体而言,

template<class...> struct Tuple { };
template< class... Types> void g(Tuple<Types ...>); // #1
// template<class T1, class... Types> void g(Tuple<T1, Types ...>); // #2
template<class T1, class... Types> void g(Tuple<T1, Types& ...>); // #3

g(Tuple<>()); // calls #1
g(Tuple<int, float>()); // calls #2
g(Tuple<int, float&>()); // calls #3
g(Tuple<int>()); // calls #3

#2未注释,g() 将按照注释中的描述进行解析。令我惊讶的是,如果我注释掉 #2行,g() 的调用解析如下:

g(Tuple<>());                     // calls #1
g(Tuple<int, float>()); // calls **#1 ???? why not #3????**
g(Tuple<int, float&>()); // calls #3
g(Tuple<int>()); // calls #3

从下面的例子和解释中我看不出为什么g(Tuple<int, float>());无法解析为 #3 .是以下两条规则的方向应用:

If a parameter pack appears as the last P, then the type P is matched against the type A of each remaining argument of the call. Each match deduces the template arguments for the next position in the pack expansion.

template<class ... Types> void f(Types& ...);
void h(int x, float& y) {
const int z = x;
f(x, y, z); // P=Types&..., A1=x: deduces the first member of Types... to int
// P=Types&..., A2=y: deduces the second member of Types... to float
// P=Types&..., A3=z: deduces the third member of Types... to const int
// calls f<int, float, const int>

If P has one of the forms that include a template parameter list <T> or <I>, then each element Pi of that template argument list is matched against the corresponding template argument Ai of its A. If the last Pi is a pack expansion, then its pattern is compared against each remaining argument in the template argument list of A. A trailing parameter pack that is not otherwise deduced, is deduced to an empty parameter pack.

最佳答案

您的两个示例之间存在误解。在第二个例子中 f ,您正在推断函数的引用参数。在第一个例子中 g ,您正在推导出对函数参数的引用模板参数。后者必须完全匹配,但前者是根据引用的类型推导出来的。它们不一样。


在你的第一个例子中,

g(Tuple<int, float>());

无法调用 g(Tuple<T1, Types&...>) .模板推导过程是关于选择一个推导的参数类型,该类型与被调用的参数类型相同。有一些异常(exception)(对于引用的 cv 限定、指针、派生类、数组、函数),但这些都不适用于此处。我们只需要选择 T1Types...这样 Tuple<T1, Types&...>Tuple<int, float> 的类型相同.这是不可能的,因为没有这样的包 Types...为此 Types&...{float} , 自 float不是引用!

因此,一旦您注释掉 (2),就只有一个可行的候选者:(1)。


另一方面,

template<class ... Types> void f(Types& ...);
void h(int x, float& y) {
const int z = x;
f(x, y, z);
}

在这里,Types&...实际上是参数本身的类型(而不是它的模板参数),所以(temp.deduct.call):

If P is a reference type, the type referred to by P is used for type deduction.

我们推断Types...匹配参数。这会成功,因为所有参数都是左值,我们只需选择 {int, float, const int} .

关于c++ - 以可变类模板作为函数调用参数的函数模板参数推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33426328/

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