在 C++0x 中专门化 lambda 模板

2023-12-26

我编写了一个特征类,它可以让我提取有关 C++0x 中函数或函数对象的参数和类型的信息(使用 gcc 4.5.0 进行测试)。一般情况处理函数对象:

template <typename F>
struct function_traits {
    template <typename R, typename... A>
    struct _internal { };

    template <typename R, typename... A>
    struct _internal<R (F::*)(A...)> {
        // ...
    };

    typedef typename _internal<decltype(&F::operator())>::<<nested types go here>>;
};

然后我在全局范围内专门研究普通函数:

template <typename R, typename... A>
struct function_traits<R (*)(A...)> {
    // ...
};

这工作正常,我可以将函数传递到模板或函数对象中,并且它可以正常工作:

template <typename F>
void foo(F f) {
    typename function_traits<F>::whatever ...;
}

int f(int x) { ... }
foo(f);

如果不将函数或函数对象传递给foo,我想传递一个lambda表达式?

foo([](int x) { ... });

这里的问题是,既没有专业化function_traits<>适用。 C++0x 草案规定表达式的类型是“唯一的、未命名的、非联合类类型”。破坏调用结果typeid(...).name()表达式上的内容似乎是 gcc 的 lambda 内部命名约定,main::{lambda(int)#1},而不是在语法上表示 C++ 类型名的东西。

简而言之,我可以在此处将任何内容放入模板中:

template <typename R, typename... A>
struct function_traits<????> { ... }

这将允许这个特征类接受 lambda 表达式?


我认为可以专门化 lambda 的特征并对未命名函子的签名进行模式匹配。这是适用于 g++ 4.5 的代码。尽管它有效,但 lambda 上的模式匹配似乎与直觉相反。我有内嵌评论。

struct X
{
  float operator () (float i) { return i*2; }
  // If the following is enabled, program fails to compile
  // mostly because of ambiguity reasons.
  //double operator () (float i, double d) { return d*f; } 
};

template <typename T>
struct function_traits // matches when T=X or T=lambda
// As expected, lambda creates a "unique, unnamed, non-union class type" 
// so it matches here
{
  // Here is what you are looking for. The type of the member operator()
  // of the lambda is taken and mapped again on function_traits.
  typedef typename function_traits<decltype(&T::operator())>::return_type return_type;
};

// matches for X::operator() but not of lambda::operator()
template <typename R, typename C, typename... A>
struct function_traits<R (C::*)(A...)> 
{
  typedef R return_type;
};

// I initially thought the above defined member function specialization of 
// the trait will match lambdas::operator() because a lambda is a functor.
// It does not, however. Instead, it matches the one below.
// I wonder why? implementation defined?
template <typename R, typename... A>
struct function_traits<R (*)(A...)> // matches for lambda::operator() 
{
  typedef R return_type;
};

template <typename F>
typename function_traits<F>::return_type
foo(F f)
{
  return f(10);
}

template <typename F>
typename function_traits<F>::return_type
bar(F f)
{
  return f(5.0f, 100, 0.34);
}

int f(int x) { return x + x;  }

int main(void)
{
  foo(f);
  foo(X());
  bar([](float f, int l, double d){ return f+l+d; });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C++0x 中专门化 lambda 模板 的相关文章

随机推荐

  • GDAL Virtualenv Python 3.6 安装

    我在安装 gdal 时经历了一段残酷的时光 我全新安装了 Ubuntu Mint 并尝试在 virtualenv Python 3 6 环境中安装 GDAL 完成所有依赖项要求后 我现在在运行后收到以下错误pip install gdal
  • 当List填充数组时,如何在SwiftUI中获取List中元素的索引?

    在我的 SwiftUI 应用程序中 我有一个项目列表 我正在使用 MenuItems 数组来填充列表 struct MenuItem Identifiable Equatable var id UUID var text String st
  • 错误:Ionic 的构造函数参数中没有 http 提供程序

    我正在学习葡萄牙语教程 该教程教授如何构建您的第一个 Ionic 应用程序 使用最新版本安装 npm node js Angular Ionic 和 Cordova 后 我开始编写代码 代码本身非常简单 import Component f
  • 适用于 ios 应用程序的 django csrf for api

    我正在构建一个 ios 应用程序 它与服务器通信以获取数据 如果它只是一个普通的应用程序 我可以通过表单发送 csrf 令牌 因为全部来自同一域 但是 对于 ios 应用程序 我认为我无法设置 csrf token 因此 当从 ios 应用
  • 通过 MVC 和 RAZOR 编写 JSON

    我有一个 ASP NET MVC 4 应用程序 这个应用程序有一个视图 页脚中有一个 JavaScript 块 我正在使用 RAZOR 视图引擎 我正在尝试弄清楚如何将结果集转换为 JSON 数组 目前 我正在执行以下操作
  • 在 Ubuntu 中安装 npm 包时出错 [重复]

    这个问题在这里已经有答案了 我有一个项目 以前工作正常 突然开始显示此错误 这是一个使用create react app创建的react项目 同样的错误npm install and npm f install sudipt sudo De
  • 想要通过在 swift 中使用滑动手势在选项卡栏之间导航

    我想使用滑动手势在选项卡栏控制器之间导航 同时保留默认选项卡栏 我使用了这段代码 但显示错误 import UIKit class FirstViewController UIViewController override func vie
  • 模拟指标有什么影响?

    使用 xib 文件时 更改模拟指标会对您的代码 应用程序产生什么影响 或者它只是为了您的利益而作为预览工具 实际上 更改模拟指标确实会以一种非常隐蔽的方式影响您的应用程序 我发现在使用 SwipeView 库时 我的幻灯片都受到更改模拟指标
  • Ubuntu 上的 Haskell (GHC) 中的线程延迟问题

    我注意到我的一些机器上 GHC Conc 中的 threadDelay 函数有奇怪的行为 以下程序 main do print start threadDelay 1000 1000 print done 正如预期的那样 运行需要 1 秒
  • 使用BackgroundWorker处理多个操作

    我在 winform 上有一个 DataGridView 我在表单的加载方法中动态添加 DatagridViewButtonColumn 按钮名称为 btnAction 文本显示为 Process 因此 网格中的每一行的最后一列都会有此 处
  • 使用导航视图菜单项上的选择器添加自定义形状波纹

    我想添加带有圆角矩形的波纹效果以及导航视图项目的选择器 但它不断添加灰色矩形波纹效果 导航视图
  • Chrome 的“跨源读取阻止 (CORB) 阻止了跨源响应”离子

    我正在尝试对用户进行身份验证 但由于以下原因我无法调用 Api跨源读取阻止 CORB 被阻止问题我的login ts代码是 if this plugins isOnline if this wait true return else if
  • 如何在c#中找到驱动器的空闲百分比

    如何在c 中找到驱动器的百分比 例如 如果 c 为 100 GB 并且已用空间为 25 GB 则可用百分比应为 75 Use the DriveInfo class http msdn microsoft com en us library
  • Facebook Webforms 应用程序获取 app_data 查询字符串

    如何从 Facebook Webforms 应用程序获取 app data 查询字符串 我希望能够在查询字符串中发送一些信息 以便我可以在我的应用程序上显示不同的主屏幕 该应用程序位于页面选项卡中 例子 如何从 app data 获取 Pa
  • 显示图像并转换为灰度 - OpenCV for Android、Java API

    我正在 Eclipse 中编写一个 Android 应用程序 它使用OpenCV4Android http code opencv org projects opencv wiki OpenCV4AndroidAPI 我怎样才能显示一个Ma
  • 从 C++ 本机插件更新 Vector3 数组

    Marshal Copy 方法仅支持少数数组类型 现在我只知道如何复制IntPtr 从 C 代码指向浮点数组 float IntPtr pvertices GetVerticesFromCPP float vertices new floa
  • 使用 linq 删除代码时出现错误

    我遇到有关使用组合框删除数据的问题 该错误提示我不知道如何解决 任何人都可以帮助我吗 private void btnDel Click object sender EventArgs e using testEntities Setupc
  • ByVal 与 ByRef VBA

    我尝试过 JaredPar 回答的问题ByRef 与 ByVal 说明 https stackoverflow com questions 4383167 byref vs byval clarification ByVal在 VB NET
  • ant 构建文件设置 javac 位置

    我正在编辑一个旧项目的构建文件 当我向使用 Java 1 6 的项目添加一些 jar 文件时 它不会构建 它说 javac javac invalid target release 1 6 很明显 我需要告诉 ant 构建文件使用 java
  • 在 C++0x 中专门化 lambda 模板

    我编写了一个特征类 它可以让我提取有关 C 0x 中函数或函数对象的参数和类型的信息 使用 gcc 4 5 0 进行测试 一般情况处理函数对象 template