不知何故,我仍然认为 lambda 是常规函数对象的“语法糖”,所以令我惊讶的是,在 C++-20 下,有状态但在其他方面
constexpr
lambda 实例不能用作非类型模板参数,这与等效函数不同对象实例。
任何人都可以解释这种行为或决定吗?
示例关于 Godbolt:
struct always_fn {
const int x;
int operator()() const
{
return x;
}
};
inline constexpr always_fn always_f{5};
// lambda equivalent to `always_f`
inline constexpr auto always_2_f = [x = 5]() {
return x;
};
template<typename F>
struct wrapped {
F f_;
};
inline constexpr auto wrapped_f = wrapped{always_f};
inline constexpr auto wrapped_2_f = wrapped{always_2_f};
template<auto f>
void pass() {}
int main() {
pass<always_f>();
pass<wrapped_f>();
// error: no matching function for call to 'pass'
pass<always_2_f>();
// ^~~~~~~~~~~~~~~~
// error: no matching function for call to 'pass'
pass<wrapped_2_f>();
// ^~~~~~~~~~~~~~~~~
return 0;
}
Lambda 永远不是 结构类型,因此永远不能用作非类型模板参数。
这已由 CWG 2542 澄清,编译器可能尚未实现。