带有自定义分配器但没有其他参数的 std::function 构造函数有什么意义?

2024-01-05

我正在玩标准::函数和自定义分配器,但当我不为函数提供初始函子时,它的行为并不像我预期的那样。

当我向构造函数提供自定义分配器但没有初始函子时,分配器永远不会被使用,或者看起来是这样。

这是我的代码。

//Simple functor class that is big to force allocations
struct Functor128
{
    Functor128()
    {}

    char someBytes[128];

    void operator()(int something)
    {
        cout << "Functor128 Called with value " << something << endl;
    }
};

int main(int argc, char* argv[])
{
Allocator<char, 1> myAllocator1;
Allocator<char, 2> myAllocator2;
Allocator<char, 3> myAllocator3;
Functor128 myFunctor;

cout << "setting up function1" << endl;
function<void(int)> myFunction1(allocator_arg, myAllocator1, myFunctor);
myFunction1(7);

cout << "setting up function2" << endl;
function<void(int)> myFunction2(allocator_arg, myAllocator2);
myFunction2 = myFunctor;
myFunction2(9);

cout << "setting up function3" << endl;
function<void(int)> myFunction3(allocator_arg, myAllocator3);
myFunction3 = myFunction1;
myFunction3(19);
}

Output:

setting up function1
Allocator 1 allocating 136 bytes.
Functor128 Called with value 7

setting up function2
Functor128 Called with value 9

setting up function3
Allocator 1 allocating 136 bytes.
Functor128 Called with value 19

所以 case1: myFunction1 按预期使用 allocator1 进行分配。

case2: myFunction2 在构造函数中被赋予 allocator2 ,但是当分配一个函子时,它似乎重置为使用默认的 std::allocator 进行分配。(因此没有打印出有关分配的信息)。

case3:myFunction3 在构造函数中被赋予了 allocator3,但是当从 myFunction1 分配时,分配是使用 function1 的分配器进行分配的。

这是正确的行为吗? 特别是,在情况 2 中,为什么要恢复使用默认的 std::allocator? 如果是这样,采用分配器的空构造函数有什么意义,因为分配器永远不会被使用。

我使用 VS2013 来编写此代码。

我的 Allocator 类只是一个最小的实现,它使用 new 并在分配时注销

template<typename T, int id = 1>
class Allocator {
public:
    //    typedefs
    typedef T value_type;
    typedef value_type* pointer;
    typedef const value_type* const_pointer;
    typedef value_type& reference;
    typedef const value_type& const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;

public:
    //    convert an allocator<T> to allocator<U>
    template<typename U>
    struct rebind {
        typedef Allocator<U> other;
    };

public:
    inline  Allocator() {}
    inline ~Allocator() {}
    inline  Allocator(Allocator const&) {}
    template<typename U>
    inline  Allocator(Allocator<U> const&) {}

    //    address
    inline pointer address(reference r) { return &r; }
    inline const_pointer address(const_reference r) { return &r; }

    //    memory allocation
    inline pointer allocate(size_type cnt,
        typename std::allocator<void>::const_pointer = 0) 
    {
        size_t numBytes = cnt * sizeof (T);
        std::cout << "Allocator " << id <<  " allocating " << numBytes << " bytes." << std::endl;
        return reinterpret_cast<pointer>(::operator new(numBytes));
    }
    inline void deallocate(pointer p, size_type) {
        ::operator delete(p);
    }

    //    size
    inline size_type max_size() const {
        return std::numeric_limits<size_type>::max() / sizeof(T);
    }

    //    construction/destruction
    inline void construct(pointer p, const T& t) { new(p)T(t); }
    inline void destroy(pointer p) { p->~T(); }

    inline bool operator==(Allocator const&) { return true; }
    inline bool operator!=(Allocator const& a) { return !operator==(a); }
};    //    end of class Allocator

std::function的分配器支持......很奇怪。

目前的规格为operator=(F&& f)是这样的std::function(std::forward<F>(f)).swap(*this);。正如你所看到的,这意味着内存f使用任何方式分配std::function默认使用,而不是用于构造的分配器*this。所以你观察到的行为是正确的,尽管令人惊讶。

而且,自从(allocator_arg_t, Allocator) and (allocator_arg_t, Allocator, nullptr_t)构造函数是noexcept,即使他们想要,他们也无法真正存储分配器(类型擦除分配器可能需要动态分配)。事实上,它们基本上是为支持使用分配器构造协议而存在的无操作。

LWG 最近被拒绝an issue http://wg21.link/lwg2386这会改变这种行为。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带有自定义分配器但没有其他参数的 std::function 构造函数有什么意义? 的相关文章

随机推荐

  • 发送电子邮件时更改文本(字符串)的颜色

    当我将文本 字符串 输出到电子邮件时 我试图更改它的颜色 我的代码是 String appdata txtFromSpinner location getText date getText start getText finish getT
  • 在 TOpenDialog 中右键单击文件时,使用自定义样式会显示无效字符

    请参阅以下步骤进行重现 在 XE2 中运行良好 但在 XE8 中运行不佳 创建新的 VCL 表单应用程序 Delphi Place a TButton and a TOpenDialog在表格上 在按钮中OnClick事件调用OpenDia
  • Matlab中值滤波器代码

    我需要在 MATLAB 中对图像实现中值滤波 然而 我是不允许使用medfilt2 or ordfilt2MATLAB 中的函数 我们最近也开始学习MATLAB 是否有任何代码可用于中值滤波器或高斯滤波器 NB 这假设已安装图像处理工具箱
  • 如何将 Comet 与 Spring MVC 一起使用?

    我想添加一些彗星 服务器推送 http en wikipedia org wiki Comet programming 简单 Web 应用程序的功能 我无法找到有关如何执行此操作的最新信息 任何人都可以向我指出一些示例 教程 博客或任何最近
  • Android ACR122U NFC 集成

    See NFC 读取器 SELECT 通过 AID APDU 未路由到 Android 设备 https stackoverflow com q 50316799 2425802关于调试和最终结果 TL DR 读者可能已经不复存在了 我的
  • 验证 Knuth 洗牌算法尽可能无偏

    我正在实施一个高德纳洗牌 http en wikipedia org wiki Fisher E2 80 93Yates shuffle对于我正在从事的 C 项目 我试图从我的洗牌中获得最公正的结果 而且我不是 伪 随机数生成方面的专家 我
  • 创建一个 firemonkey 组件

    我正在 Delphi XE4 中使用 Firemonkey 但无法使用菜单项 Component gt New Component 创建新组件 无论该组件是 VCL 还是 Firemonkey 组件 或者我是否先创建一个包 结果都是相同的
  • 如何从命令行执行 SOAP wsdl Web 服务调用

    我需要进行 SOAP Web 服务调用https sandbox mediamind com Eyeblaster MediaMind API V2 AuthenticationService svc wsdl https sandbox
  • 事件处理程序性能

    我有性能问题 我创建了 100 个新按钮 并且想要分配一个单击事件处理程序 我执行这段代码大约 100 次 Buttons i Button Click new System EventHandler Button Click 大约需要2秒
  • 发送参数到before_save

    我正在尝试以 rails 方式 构建一个应用程序 所以这次我不是回顾性地处理数据库中的记录 而是尝试使用 before save 方法来完成它们 即这个 def make percentage from score percent scor
  • 如何在 Dart 中合并两个列表?

    我想知道是否有一种简单的方法可以在 dart 中连接两个列表来创建一个全新的列表对象 我找不到任何东西和类似的东西 My list list1 1 2 3 list2 4 5 6 I tried var newList list1 list
  • 在python中通过ftp更改权限

    我正在使用 pythonftplib将图像上传到我的 raspberryPi 上位于 var www 的文件夹中 一切工作正常 除了上传的文件有600权限和我需要644对于他们来说 哪种方法最好 我正在寻找类似的东西 def ftp sto
  • PhpStorm - 导航后退键盘快捷键不起作用

    When I Ctrl click on method it will jump to declaration of that method 问题 如何跳回到该方法的使用 I tried Ctrl Alt Left combination
  • 用于随机森林分类的​​ ROC 曲线

    我在用randomForestR平台中用于分类任务的包 rf object lt randomForest data matrix label factor cutoff c k 1 k 其中 k 的范围为 0 1 到 0 9 pred l
  • 如何在 Ruby on Rails 中分析请求?

    如何分析控制器操作 我的一个观点是渲染需要相当长的时间 我想把它分解一下 我懂了script performance profiler 但这似乎只能访问全局范围 红宝石教授 http ruby prof rubyforge org 是要走的
  • 如何轻松获取 Scala 案例类的名称?

    Given case class FirstCC def name String something that will give FirstCC case class SecondCC extends FirstCC val one Fi
  • pyspark approxQuantile 函数

    我有包含这些列的数据框id price timestamp 我想找到按以下分组的中值id 我正在使用此代码来查找它 但它给了我这个错误 from pyspark sql import DataFrameStatFunctions as st
  • 如何使用angularjs动态显示表中的对象数组?

    我使用 angular js 作为我的字体端 使用 node js 作为服务器端 使用 PostgreSQL 作为数据库 现在 我在数据库中有一些值列表 数据库 控制器代码 我得到以下输出console console log scope
  • 计算二维数组的页面错误数

    我正在努力学习考试 我找到了这个例子 但不明白他们是如何得到答案的 有人可以解释一下吗 问题 考虑二维数组 A int A 新 int 100 100 其中 A 0 0 位于页大小为 200 的分页内存系统中的位置 200 操作矩阵的小进程
  • 带有自定义分配器但没有其他参数的 std::function 构造函数有什么意义?

    我正在玩标准 函数和自定义分配器 但当我不为函数提供初始函子时 它的行为并不像我预期的那样 当我向构造函数提供自定义分配器但没有初始函子时 分配器永远不会被使用 或者看起来是这样 这是我的代码 Simple functor class th