为什么第一个调用无法编译?
auto get1 = []<int B>() { return B; };
auto get2 = []<typename B>(B b) { return b; };
int main()
{
get1<5>(); // error: no match for operator<
get2(5); // ok
}
我之所以使用它,是因为该表达式在代码中多次重复。
当然,我可以使用真正的功能模板,但是我很好奇。
最佳答案
如果考虑等效类类型是get1
的样子,这将更容易理解:
struct get1_t {
template <int B> operator()() const { return B; }
};
get1_t get1;
get1<5>(); // error
您正在尝试为调用运算符提供一个显式的模板参数,但是从语法上讲,您正在执行为
get1
本身提供模板参数的操作(即好像get1
是一个变量模板)。为了为调用运算符提供模板参数,您必须直接执行以下操作:get1.operator()<5>(); // ok
或重组调用运算符以采用某种可推论的方法:
template <int B> struct constant { };
get1(constant<5>{});
或者将整个结构重组为实际上是看起来像是的变量模板:
template <int B>
auto get1 = [] { return B; };
现在,
get1<5>
本身就是您要调用的lambda。也就是说,除了具有调用运算符模板的lambda之外,我们还有可变模板lambda本身不是模板。