首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无参数模板参数的自动检测

无参数模板参数的自动检测
EN

Stack Overflow用户
提问于 2014-06-24 15:41:27
回答 2查看 536关注 0票数 4

这是an answer对另一个SO post的一个分支。

我有下面的工作代码,具有预期的输出。

代码语言:javascript
复制
#include <iostream>

template <typename T>
T twice(T in)
{
   return 2*in;
}

struct Foo
{
   Foo operator+(int (*func)(int in)) const
   {
      Foo ret{data};
      ret.data += func(ret.data);
      return ret;
   }
   int data;
};

int main()
{
   Foo f1{20};
   Foo f2 = f1 + twice;
   Foo f3 = f1 + twice<int>;
   std::cout << f2.data << std::endl;
   std::cout << f3.data << std::endl;
}

直到昨天,我才知道编译器可以在没有参数的情况下推断函数模板的类型参数。在上面的代码中,表达式

代码语言:javascript
复制
f1 + twice

代码语言:javascript
复制
f1 + twice<int>

结果是相同的值。

我的问题是:在C++03/C++11标准中,我们可以为编译器的自动类型检测逻辑找到必要的支持文档吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-24 16:45:42

这与实际的c++11标准最接近,但我发现的草稿http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf仍然公开可用。

我相信模板参数的推导是在编写Foo f2 = f1 + twice;并将twice作为函数地址传递时完成的。twice作为函数的地址传递给operator+。我相信以下机制起作用:

14.8.2.2使用函数模板temp.deduct.funcaddr的地址推导模板参数的: 当获取重载函数(13.4)的地址时,模板参数可以从specified类型中推导出来。函数模板的函数类型和specifi编辑类型作为P和A的类型,并按14.8.2.5中的描述进行了推导。

因此,实际的模板演绎将根据funct的类型进行。我相信14.8.2.5的相关段落是1和2。

14.8.2.5从类型temp.deduct.type`推断模板参数: 1模板参数可以在多个双ff传入上下文中推导,但在每种情况下,都会将一种按模板参数(称为P )与实际类型(称为A)进行比较的类型,并尝试对fi和模板参数值(类型参数的类型、非类型参数的值或模板参数的模板)进行比较,在替换推导值(称为A)之后,使之与A兼容。 2在某些情况下,推导使用一组P和A类型,在另一些情况下,将有一组对应的类型P和A。对每一对P/A分别独立地进行类型推导,然后将推导出的模板参数值组合起来。如果不能对任何P/A对进行类型推导,或者对任何对进行推演会导致多个可能的推断值集,或者如果双ff传入法对产生双ff推导值,或者如果任何模板参数既没有推导也没有显式地说明fied,则模板参数推导失败。

基本上,您将twice作为指向operator+的指针传递,然后通过operator+中定义的函数类型推导模板参数。因此,您有一个实际的类型A,即int (*)(int in)和模板类型P of twice,它们与A匹配,只有int twice(int)适合。

我希望我把一切都做对了。

票数 3
EN

Stack Overflow用户

发布于 2014-06-24 16:44:30

C++11 14.8.2.2模板参数可以从使用重载函数的地址时指定的类型推导出来。

这里,operator+的参数类型指定的类型是int (*)(int),重载的函数是twice,因此int被推导为模板参数,从而给出匹配的函数类型。如果您需要扣减的血淋淋的细节,请参阅14.8.2.5。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24390911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档