我有下面的工作代码,具有预期的输出。
#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;
}
直到昨天,我才知道编译器可以在没有参数的情况下推断函数模板的类型参数。在上面的代码中,表达式
f1 + twice
和
f1 + twice<int>
结果是相同的值。
我的问题是:在C++03/C++11标准中,我们可以为编译器的自动类型检测逻辑找到必要的支持文档吗?
发布于 2014-06-24 08: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)
适合。
我希望我把一切都做对了。
发布于 2014-06-24 08:44:30
C++11 14.8.2.2模板参数可以从使用重载函数的地址时指定的类型推导出来。
这里,operator+
的参数类型指定的类型是int (*)(int)
,重载的函数是twice
,因此int
被推导为模板参数,从而给出匹配的函数类型。如果您需要扣减的血淋淋的细节,请参阅14.8.2.5。
https://stackoverflow.com/questions/24390911
复制相似问题