c++ - 为什么我不能使用 labmda 作为非类型模板参数?
问题描述
我想使用 lambda 作为模板参数,但它不会在 c++17 中编译。例如temp_bar<int, lambda1>
这里不起作用。似乎非类型参数是有限的。谁能解释为什么不允许这样做?启用此功能将使生活变得更加容易。
template<typename T>
bool to_bool(T o)
{
return bool(o);
}
template <typename T, auto F=to_bool<T>>
class temp_bar
{
public:
temp_bar(T o)
: _data{o}
{
if(F(o))
std::cout << "OK\n";
}
private:
T _data;
};
int main()
{
temp_bar<int> bar1{1};
auto lambda1 = [](int o){return o==2;};
temp_bar<int, lambda1> bar2{2};
return 0;
}
解决方案
忽略lambda1
is not的声明,constexpr
因此不是常量表达式,因此无论如何都不能用作非类型模板参数(NTTP)这一事实,不允许这样做的主要原因是 lambdas 不是C ++中的特殊事物。lambda 只是由编译器创建的用户定义类型,具有专门的构造函数、基于捕获列表的成员以及operator()
符合 lambda 函数体和签名的重载。没有它们,lambda 所做的一切都是你做不到的。
在 C++ 中,lambda 只是简写符号;而已。
因此,如果用户定义的类型不能用作 NTTP,而 lambda 是用户定义的类型,那么您不能将 lambda 用作 NTTP。这就是他们被禁止的原因。
请注意,虽然 C++20 确实允许将某些用户定义的类型用作 NTTP,但目前的标准不保证任何特定的 lambda 是否可以用作 NTTP。用作 NTTP 的用户定义类型必须提供强大的结构相等性,并且标准中的任何内容都不需要任何 lambda,即使是无捕获的 lambda,也必须提供强大的结构相等性。一个实现可以这样做,但是这样的代码是不可移植的。
推荐阅读
- javascript - 在提交之前将值传递给隐藏的输入值
- powershell - 从快捷方式启动时,Powershell 脚本崩溃
- r - R中ggplot2中多个图例的图例键之间的间距
- python - 创建后如何杀死类的实例以释放python中的内存?
- javascript - 将复杂对象从视图发送到 MVC 操作作为无 ajax 调用
- plugins - Flutter Firebase 插件正确的版本控制
- python - 卡夫卡与烧瓶。KafkaTimeoutError:60.0 秒后无法更新元数据
- python - Selenium 定位方法不会为 PyAutoGui 返回相同类型的坐标
- python - 如何从 CLI 访问我的自定义 python 脚本以便它们对任何文件执行操作?
- java - Java JPA 负载平衡读取查询以读取 MySql DB 从站