【发布时间】:2021-11-27 15:28:42
【问题描述】:
我试图了解模板参数推导在 C++ 中的工作原理。所以写出不同的例子。下面给出了一个这样的例子,它不起作用,我不明白为什么:
#include<iostream>
template<int var, typename T>
void func (T x)
{
std::cout<<x<<std::endl;
}
template<typename T>
void SomeFunc(T a)
{
a(6);
}
int main()
{
func<5, int>(10);//this work as expected
func<5>(20);//this works as well using template argument deduction
SomeFunc(func<5,int>) ;//this works as well
//the next two calls doesn't work
SomeFunc(func<5>);//this doesn't work. Why doesn't template argument deduction works here
SomeFunc(func<5>(20));//this doesn't work either.
return 0;
}
在上面的例子中,SomeFunc(func<5>); 语句不起作用。我的想法是,当编译器尝试实例化SomeFunc<> 时,它需要它的模板类型参数。但是我们已经将func<5> 作为函数调用参数传递了,而没有实际调用(将调用参数指定给func 本身)func 所以没有办法推导出第二个参数,所以它不起作用。我的第一个问题是我对为什么这个调用失败的分析正确吗?如果没有,那为什么它不起作用。
接下来在SomeFunc(func<5>(20)); 语句中,我将函数调用参数20 指定为func,这在之前的调用中没有指定。但这种说法仍然不起作用。 为什么会这样?
在阅读模板参数推导时,我还发现了以下声明:
扣费仅适用于即时通话。
但我不明白上面引用的陈述是什么意思。它可能与完整类型或不完整类型用作模板参数的事实有关,但我不确定。
【问题讨论】:
-
func返回void。您不能拥有SomeFunc正在尝试做的 void 类型的对象。 -
但是
SomeFunc(func<5,int>) ;是如何工作的呢?这里我们有相同的函数模板func,它返回void -
func<5,int>不调用该函数。相反,它命名了一个函数对象,该对象衰减为一个函数指针,其地址指向func<5,int>函数。 -
func<5>不起作用,因为编译器在传递函数指针时不知道第二个模板参数是什么。当您调用该函数时,它会返回 void,因此会中断。func<5, int>有效,因为它将func<5,int>函数指针传递给SomeFunc
标签: c++ c++11 templates c++17 template-argument-deduction