问题标签 [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 投票
4 回答
2311 浏览

c++ - 具有未推断上下文的函数模板的部分排序

在阅读另一个问题时,我遇到了部分排序问题,我将其缩减为以下测试用例

对于这两个函数模板,进入重载决议的特化的函数类型是void(int, void*). 但是偏序(根据 Comeau 和 GCC)现在说第二个模板更专业。但为什么?

让我通过部分排序并显示我有问题的地方。可能Q是一种独特的组合类型,用于根据 确定偏序14.5.5.2

  • 转换后的参数列表T1(Q 插入)(Q, typename Const<Q>::type*):。参数的类型是AT=(Q, void*)
  • T2(Q 插入): BT=的转换参数列表(Q, void*),这也是参数的类型。
  • 未转换的参数列表T1(T, typename Const<T>::type*)
  • 未转换的参数列表T2(T, void*)

由于 C++03 没有明确说明这一点,我确实使用了我在几个缺陷报告中读到的意图。上面转换的参数列表T1AT由我调用)用作14.8.2.1 “从函数调用中推导出模板参数”的参数列表。

14.8.2.1不再需要转换ATorBT本身(例如,删除引用声明符等),并直接转到14.8.2.4,对于每个A/P对独立地进行类型推导:

  • AT反对T2:。是这里唯一的模板参数,它会发现必须是. 类型推导对于against轻而易举地成功。{ (Q, T), (void*, void*) }TTQATT2

  • BT反对T1:。它会发现is , too here。是一个未推断的上下文,因此它不会用于推断任何内容。{ (Q, T), (void*, typename Const<T>::type*) }TQtypename Const<T>::type*


这是我的第一个问题:现在这将使用Tdeduced 的值作为第一个参数吗?如果答案是否定的,那么第一个模板更专业。这不可能,因为 GCC 和 Comeau 都说第二个模板更专业,我不认为他们错了。所以我们假设“是”,然后void*插入T. 段落 ( 14.8.2.4) 说“对每一对独立进行推导,然后将结果组合起来”以及“但是,在某些情况下,该值不参与类型推导,而是使用推导出来的模板参数的值在别处或明确指定。” 这听起来也像“是”。

因此,对于每个 A / P 对,演绎也成功。现在,每个模板至少和另一个模板一样专业化,因为演绎也不依赖于任何隐式转换并且在两个方向上都成功了。因此,调用应该是模棱两可的。

所以我的第二个问题:现在,为什么实现说第二个模板更专业?我忽略了哪一点?


编辑:我测试了显式特化和实例化,并且在最近的 GCC 版本 ( 4.4) 中都告诉我对特化的引用是模棱两可的,而旧版本的 GCC ( 4.1) 不会出现这种模棱两可的错误。这表明最近的 GCC 版本对函数模板的偏序不一致。

0 投票
2 回答
1043 浏览

c++ - Template deduction in dynamic_cast

I have a class that is defined as the following:

Inside a function I am doing this:

and it resolves the CometWidget type, complies and run correctly.
The code runs inside the CometWidget class.

How on earth does this happen?
Why is that so? Should it even compile?

0 投票
6 回答
15272 浏览

c++ - 基于返回类型的函数模板推导?

我希望能够使用模板推导来实现以下目标:

而不是(我目前拥有的):

我当前的分配函数如下所示:

这有可能取消额外的<A><B>吗?

0 投票
2 回答
3054 浏览

c++ - 使用 shared_ptr 到 const T 的 C++ 模板实例化

假设我有一堂课

以下不编译:

编译器错误是:

编译器无法std::tr1::shared_ptr<std::vector<float> > 输入 std::tr1::shared_ptr<const std::vector<float> >第一个参数。然而它可以用于第二个(非模板参数)。

对此的一种解决方案是将调用更改为 f(),像这样调用它f<float>(...)
另一种解决方案是将 v1 声明为 shared_ptr 以const vector<float>.

  1. 为什么模板实例化在这里表现如此不同?
  2. 我对shared_ptr<const T>方法的 as 参数的理解是,该方法不能改变shared_ptr指向的内容。如果我们将shared_ptrs 更改为原始指针和v1v2作为指向 的原始指针vectors,那么代码将编译得很好。shared_ptr打破模板推导的 s 是什么?
0 投票
1 回答
252 浏览

c++ - 调用模板函数时的C++模板推导

FastDelegate指的是http://www.codeproject.com/KB/cpp/FastDelegate.aspx,但我不认为它是相关的。

我有如下代码,但出现错误。

如果更改main()为:

或者:

我认为,MakeProp()应该得到Tfrom fdGetter (即int,比FastDelegate1<int>自动调用的构造函数。但它没有。为什么?

PS 我想将 getter 和 setter 保存在 中Prop,欢迎对这种方法提出任何建议。在函数中传递参数时复制 FastDelegate* 的实例可能是不好的。

0 投票
2 回答
279 浏览

c++ - Deducing knowledge of original types, whilst simultaneously forwarding

Summary: I want to end up with a function that deduces the exact types it was called with and takes (e.g.) a tuple that forwards them (the types of which will be different from the exact types the function was called with).

I'm stuck trying to "know" via deduction the types of the arguments to a given function, whilst simultaneously forwarding them. I think I might be missing something crucial about how this works.

What I'd like to see is a scenario where when my function (e.g. g1 or g2) gets called it knows and can use both the original types - int,double,void*,std::string&,const char* and the forwarded arugments too.

In this instance I don't seem to be able to find this information from within g1 or g2. The (deliberate, to print out the types) linker error shows me in g1 they are:

and in g2:

There are two thing I don't get here:

  1. Why do none of the printed (via the linker error) types match what I actually passed in? (int,double,void*,std::string&,const char). Can I deduce what I actually was passed? Preferably with "natural" syntax, i.e. everything just once and nothing explicitly written out. I can explicitly write:

    but that's "unwieldy" to say the least!

  2. In g1 the presence of && in the function signature declaration seems to alter the types in the template parameter Args itself. Compare that with:

    Or:

    using either of those with:

    doesn't change the type of T. Why does the && change the type of T itself when & doesn't?

0 投票
3 回答
3960 浏览

c++ - 获得正确的 value_type

在我的班上,我有一个成员:

现在我想要一个 fnc 返回内存的第一个元素中的内容,但我不想指定std::string为返回类型,以防以后我决定为此目的使用不同的类型,所以我尝试了这个,但它没有工作:

任何想法如何以最通用的方式指定返回类型?

0 投票
1 回答
1290 浏览

c++ - 非推导上下文中模板参数推导的解决方法

考虑以下代码:

这不会编译,因为typename outer<T>::inner它是一个非推导上下文(如此所述),这意味着编译器无法推导模板参数类型(请阅读此答案以了解原因)。正如我所看到的,我有两种选择可以让它发挥作用:

  1. 移出并使其成为类模板innerouter我更喜欢这个,因为对使用代码的影响更小。
  2. 将 - 方法添加to_string到内部。

是否有任何其他解决方案(不会导致使用代码中的难看语法)?

0 投票
2 回答
1785 浏览

c++ - 是否可以在没有编译失败的情况下推断类型是否不完整?

我想实现像 sizeof(complete_type) 这样的行为将返回真正的 sizeof,而 sizeof(incomplete_type) - 将只是 0

我需要它来为 IPC(进程间)通信提供扩展的运行时类型信息,每种类型的描述结构:

当进入我的系统时出现问题,例如 class MyOnlyDeclaredClass; 我得到了编译错误,显然是因为我无法确定它的大小。

boost type_traits http://www.boost.org/doc/libs/1_48_0/libs/type_traits/doc/html/index.html建议许多编译时类,但没有“is_incomplete”

有趣的编译器有 VS2008、VS2010、clang 3、gcc-4.6、gcc-4.7

0 投票
2 回答
1298 浏览

c++ - 为什么 `std::reference_wrapper`s 中不能推导出模板实例?

假设我有一些 type 的对象T,我想把它放到一个引用包装器中:

现在我可以很容易地说if (p < q),因为引用包装器已经转换为它的包装类型。一切都很开心,我可以处理一组引用包装器,就像它们是原始对象一样。

(正如下面链接的问题所示,这可能是生成现有集合的替代视图的有用方法,可以随意重新排列而不产生完整副本的成本,以及保持与原始集合的更新完整性。 )


但是,对于某些类,这不起作用:

我的解决方法是定义一个谓词,如this answer *; 但我的问题是:

为什么以及何时可以将运算符应用于引用包装器并透明地使用包装类型的运算符?为什么会失败std::string?它与std::string模板实例有什么关系?

*)更新:根据答案,似乎 usingstd::less<T>()是一个通用的解决方案。