问题标签 [template-argument-deduction]

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 投票
3 回答
425 浏览

c++ - C++11、14 或 17 是否提供了一种仅从 decltype() 中获取参数的方法?

这个问题非常类似于:“ Extract just the argument type list from decltype(someFunction) ”。我不确定那里的答案是否适用于我的意图。我希望能够创建一个模板函数,该函数根据函数指针模板参数(whistles)的类型推断其运行时参数的类型。

对于一个示例用例,假设我想使用加载了 LD_PRELOAD 的 shim 库来检测直接的 C POSIX 文件 I/O。我可以为 fopen、fread、fwrite、fclose 编写单独的包装器......如果所有这些包装器都做类似的事情,如果我可以定义一个捕获常见行为的模板,那不是很好吗?

不使用模板来演示涉及多少样板的部分示例:

我们可以使用可变参数模板函数保存一些代码:

不过,我们必须有某种方法可以避免在模板参数列表中传递所有这些冗余类型。我想做的事情是我还没有找到有效的语法(假设存在我称之为 std::arguments_of 的东西,有点像 std::result_of 的反面):

在 C++11、14 或 17 中是否有有效的方法来执行此操作?如何,或者如果不是,为什么不呢?

0 投票
2 回答
672 浏览

c++ - 带有模板模板参数的 C++ 函数失败模板参数推导/替换

我正在尝试使用模板模板参数为 C++ STL 容器编写一个通用的幂集函数。问题归结为以下模板参数推导/替换失败:

代码和编译器错误(使用 g++ (GCC) 4.8.1 20130531 (Red Hat 4.8.1-1))如下。我注释掉了与编译器错误无关的部分。

下面是编译器错误:

0 投票
1 回答
683 浏览

c++ - 可变参数函数指针形参的模板实参推导——不明确情况的处理

考虑以下代码:

目的是分别尝试正文中的每一行main()。我的期望是所有四个调用都是模棱两可的,并且会导致编译器错误。

我在以下位置测试了代码:

  • Clang 3.6.0 和 GCC 4.9.2,都使用-Wall -Wextra -pedantic -std=c++14( -std=c++1yfor GCC) - 在所有这些情况下的行为相同,除了错误消息的措辞略有不同;
  • Visual C++ 2013 Update 4 和 Visual C++ 2015 CTP6 - 同样的行为,所以我将它们称为“MSVC”。

Clang 和 GCC:

  • #1: 编译器错误,带有令人困惑的消息,基本上no overload of 'f' matching 'void (*)()'。什么?无参数声明从何而来?
  • #3:编译器错误,带有另一个令人困惑的消息:couldn't infer template argument 'T'。在所有可能失败的事情中,推论 forT将是我所期望的最后一个......
  • #2and #4:编译时没有错误和警告,并选择第一个重载。

对于所有四种情况,如果我们消除其中一个重载(任何一个),代码编译良好并选择剩余的函数。这看起来像是 Clang 和 GCC 中的不一致:毕竟,如果两个重载分别推导成功,那么在 case#2和中如何选择一个而不是另一个#4?他们俩不是绝配吗?

现在,MSVC:

  • #1,#3#4: 编译器错误,带有很好的消息:cannot deduce template argument as function argument is ambiguous. 现在这就是我要说的!可是等等...

  • #2:编译没有错误和警告,并选择第一个重载。分别尝试两个重载,只有第一个匹配。第二个产生错误:cannot convert argument 1 from 'void (*)(int,short)' to 'void (*)(int)'. 不再那么好了。

为了澄清我在寻找什么 case #2,这就是标准(N4296,C++14 final 之后的初稿)在 [14.8.1p9] 中所说的:

模板实参推导可以扩展与模板形参包对应的模板实参序列,即使该序列包含显式指定的模板实参。

看起来这部分在 MSVC 中不太适用,使其选择第一个重载为#2.

到目前为止,看起来 MSVC 虽然不太正确,但至少是相对一致的。Clang 和 GCC 是怎么回事?根据每种情况的标准,正确的行为是什么?

0 投票
1 回答
569 浏览

c++ - 模板推导不适用于函数指针引用

我正在使用弯路,我发现他们使用的演员表非常难看,所以我编写了几个模板函数来为我做演员表。

这使我可以进行以下调用:

但是,我想知道是否可以将两个函数名称合并fnPtrRefToVoidPtrReffnPtrToVoidPtr一个名称。

执行以下操作不起作用,因为它无法推断出模板参数:

导致以下错误:

使用我原来的功能,这工作正常:

但是,如果我改成fnPtrRefToVoidPtrRef这样:

我收到以下错误:

这似乎是为什么它不能进行模板推导,它不承认它是相同的(或可转换的?)类型。有没有办法让 C++ 正确推断出函数指针?

0 投票
0 回答
200 浏览

c++ - 自动作为模板参数

为什么不正确?将 auto 推断为 char 有什么问题?

0 投票
5 回答
1532 浏览

c++ - 无法推断模板类型

我试图将迭代器作为模板参数传递给模板方法,但编译器抱怨:

产生错误的代码是:

我猜有一种简单的方法可以完成这项工作,因为大多数标准算法都可以从迭代器中推断出类型。

0 投票
2 回答
229 浏览

c++ - 可变参数函数模板中未推断上下文

据我所知,以下代码应该是“不推断上下文”(或不是?)

f但是 g++ 4.9 为in的两个实例编译它main...有人能解释一下吗?

0 投票
2 回答
329 浏览

c++ - C++03中的模板函数返回类型推导

我想在 C++03 中实现以下内容:

除了我想打电话convert而不必明确指定T1. 我怎么做?

0 投票
1 回答
1048 浏览

c++ - C++,将自定义占位符与函数参数匹配

我正在尝试编写将执行以下操作的代码:假设我们调用了自定义绑定函数

在我们拥有之后

其中函数 some_func:

如何将占位符与实际函数调用中提供的参数匹配,即 bind_obj(...)?

换句话说,是否可以遍历 std::tuple (此处的参数和占位符)和可变参数包(函数参数):

  1. 推导出函数 some_func 的返回类型;
  2. 制作正确的 std::tuple 以在 some_func() 调用中进一步使用它?

我正在尝试不使用 boost 和 std::functional 来做到这一点。我认为,我的主要问题是我不明白如何在运行时使用参数构建元组(所有占位符都正确替换)并推断返回类型。

我在 STL "functional.h" 中看到了 _Mu 模板结构,但它看起来过于复杂且过载。

0 投票
1 回答
218 浏览

c++ - 当函数参数是对 T 的 const 引用时,为什么 T 的模板参数推导会“跳过”数组元素的常量性?

让我们考虑这些定义:

带有指向 const 的指针

如果执行以下语句:

输出是:

所以T实际上被推断为一个指向一个常量整数的指针。参数是对 const 的引用这一事实不会改变推论,这是人们所期望的,因为指针的 const 是低级的。

但有 const 数组

尽管如此,如果执行以下语句:

输出是:

所以T实际上被推导出为 3 个非常量整数的数组。参数是对 const 的引用这一事实确实改变了推论,就好像它const滑入了数组元素一样。

实际上,最多 18 个版本的 CL 推断T为 3 个 const 整数的数组是我期望的标准,但似乎自 v19 以来它收敛到 GCC 和 Clang 正在做的事情(即推断为非常量)。

因此,我认为后来的行为是标准的,但这是基本原理吗?它的行为与指针不同,这似乎令人惊讶。


编辑:发表评论之后,我将在这里报告与此行为相关的 CWG 问题的指针,他实际上作为对此答案的评论发布的指针(实际上提出了这个新问题的答案...... C++ 感觉就像一条深隧道)