首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在initializer_list参数的情况下调用std::make_shared?

在C++中,std::make_shared函数用于创建一个shared_ptr对象,并将其初始化为给定的参数。然而,当我们想要使用initializer_list作为参数时,std::make_shared函数并不直接支持。但是我们可以通过一些技巧来实现在initializer_list参数的情况下调用std::make_shared。

首先,我们需要定义一个辅助函数,该函数将使用可变模板参数和递归调用来处理initializer_list中的每个元素。然后,我们可以将这个辅助函数作为参数传递给std::make_shared函数。

下面是一个示例代码:

代码语言:txt
复制
#include <iostream>
#include <memory>
#include <initializer_list>

template<typename T, typename... Args>
std::shared_ptr<T> make_shared_helper(Args&&... args) {
    return std::make_shared<T>(std::forward<Args>(args)...);
}

template<typename T, typename... Args>
std::shared_ptr<T> make_shared_with_initializer_list(std::initializer_list<T> initList, Args&&... args) {
    return make_shared_helper<T>(initList, std::forward<Args>(args)...);
}

int main() {
    auto sp = make_shared_with_initializer_list<int>({1, 2, 3});
    for (const auto& num : *sp) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

在上面的示例代码中,make_shared_helper函数用于处理initializer_list中的每个元素,并将其传递给std::make_shared函数。make_shared_with_initializer_list函数则将initializer_list作为第一个参数,并将其余参数传递给make_shared_helper函数。

通过这种方式,我们可以在initializer_list参数的情况下调用std::make_shared,并且可以使用std::shared_ptr来管理动态分配的对象。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云函数计算(云原生):https://cloud.tencent.com/product/scf
  • 腾讯云云服务器(CVM):https://cloud.tencent.com/product/cvm
  • 腾讯云数据库(TencentDB):https://cloud.tencent.com/product/cdb
  • 腾讯云对象存储(COS):https://cloud.tencent.com/product/cos
  • 腾讯云区块链服务(BCS):https://cloud.tencent.com/product/bcs
  • 腾讯云人工智能(AI):https://cloud.tencent.com/product/ai
  • 腾讯云物联网(IoT):https://cloud.tencent.com/product/iot
  • 腾讯云移动开发(移动推送、移动分析、移动测试等):https://cloud.tencent.com/product/mobile
  • 腾讯云音视频服务(VOD):https://cloud.tencent.com/product/vod
  • 腾讯云安全产品(DDoS防护、WAF、安全加速等):https://cloud.tencent.com/product/safety
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++:20---类模板(template)

Blob{public:Blob();Blob(std::initializer_list i);}; 模板类使用: 在定义类时,使用到类名地方都需要显示给出模板类类型,格式为 int...();Blob(std::initializer_list i);T func(T const &str);//在类内声明}; //类外定义template T Blob<...}; template template Blob::Blob(It b, It e):data(std::make_shared<std::vector...” 注意:成员模板不能为虚函数 ①普通(非模板)类成员模板 概念:我们可以在一个非模板类中定义一个成员模板 演示案例 默认情况下,unique_ptr会调用元素析构函数来删除元素。...在此情况下,类和成员各自有自己、独立模板参数 演示案例 例如下面Blob是一个类模板,模板类型为T数据成员vector类型也为T。

1.2K20
  • c++模板与泛型编程

    默认情况下,一个类模板成员函数只有当程序用到它时才进行实例化。 在类模板自己作用域中,我们可以直接使用模板名而不提供实参。...一个特定文件所需要所有模板声明通常一起放置在文件开始位置,出现于任何使用这些模板代码之前。 默认情况下,C++语言假定通过作用域运算符访问名字不是类型。...::make_shared>(b, e)) { } 1.5 控制实例化 当模板被使用时才会进行实例化这一特性意味着,相同实例可能出现在多个对象文件中。...initializer_list参数构造函数和拷贝构造函数实例。...其他类型转换,算术转换、派生类向基类转换以及用户定义转换,都不能应用于函数模板。

    60620

    4.2 C++ Boost 内存池管理库

    Boost库已被广泛应用于许多不同领域C++应用程序开发中,网络应用程序、图像处理、数值计算、多线程应用程序和文件系统处理等。...; std::system("pause"); return 0;}一般在默认情况下object_pool内存池只能接收三个以内参数传递,当读者需要使用多于三个参数时则需要使用自定义可变参数模板来实现功能...::make_shared();}int main(int argc, char const *argv[]){ // 第一种调用方式 auto ptr = create(); ptr...>>()){} shared_vector(initializer_list il) : data(make_shared>(il)){} size_type...::system("pause"); return 0;}weak_ptr还可以用于对象自我管理,获得this指针shared_ptr使对象自己能产生shared_ptr管理自己,使用时需要定义类

    78940

    《Effective Modren C++》 进阶学习(上)

    理解auto类型推导 在大部分情况下auto推导与模板类型推导一致,仅当变量使用花括号初始化时,auto能够推导成std::initializer_list,而模板类型推导则无法推导。...另外,在构造函数有参数情况中,若不包含std::initializer_list参数或者 构造未传入实参,()和{}产生一样效果,否则{}优先匹配std::initializer_list参数构造函数...w8{std::move(w4)}; // 使用花括号,调用std::initializer_list构造函数 接着上述,在使用{}初始化时,只要参数能强转换为initializer_list...要求变窄转换 只有当传入参数在编译器上无法转换成std::initializer_listT类型,才会匹配普通构造函数。...在构造重载匹配中,只要参数能够强转std::initializer_listT,就会匹配std::initializer_list构造函数,即便有更加匹配构造函数。

    19620

    Chapter 4: Smart Pointers

    不能拷贝,只能移动,析构时非空 std::unique_ptr 会销毁它资源,默认情况下std::unique_ptr 会对内部原始指针使用 delete 来释放原始指针所指向资源。...,因为多个使用者可能并发读写该引用计数 构造 std::shared_ptr 在移动构造情况下,不会对引用计数进行修改 std::shared_ptr 自定义析构器和 std::unique_ptr...在这个情况下调用者从工厂函数中收到智能指针,然后由调用者来决定它声明周期,而当指向某个 id 最后一个使用指针销毁时,对象也会被销毁,那么缓存中指针就会悬空,因此在后续查询时候需要检测命中指针是否已经悬空...std::make_shared std::make_unique std::allocate_shared: 它表现地和 std::make_shared 一样,除了第一个参数是用于动态内存分配分配器对象...,如果要使用花括号初始器来构造智能指针,必须直接使用 new ,但是完美转发不能直接转发花括号初始化列表,必须先保存为 std::initializer_list 对象,然后在传递给 std::make_XX

    1.6K20

    智能指针在面试中得重要地位!

    : 1,std::make_shared 总是创建一个控制块,它会生产出一个用来指涉到新对象,因此在调用时刻,不会有针对该对象而控制块存在 2,从具备专属所有权指针(std::unique_ptr...::make_shared(), computePriority()); /* 因为:不管哪个先被调用,总能析构掉 1, std::make_shared首先被调用...得析构函数也能知道他拥有得Widget已被析构 2, 如果 computePriority先被调用并产生了异常,std::make_shared将不会被调用,因此也不用担心 */...= std::make_shared>(10,20); //如果用 {}则必须这样做 //创建 std::initializer_list型别得对象 auto initList...= {10,20}; //利用 std::initializer_list型别得构造函数构造 std::vector auto spv1 = std::make_shared<std::vector<

    1K20

    初始化|这些年踩过

    默认初始化:Type variable; 这些初始化方式依赖于其具体类型 •对于基础类型,则可以使用赋值方式直接初始化 int a = 42; double b = 1.2; •对于类类型,在其只有一个参数情况下...,从使用方式上来看,更加统一,显然统一初始化是我们进行初始化时候首选,当然了,需要注意一些细节,尤其是对于存在参数std::initializer_list容器类型来说。...编译器有个特点,对于以花括号初始化方式则认为是统一初始化,如果构造函数中同样存在std::initializer_list参数构造函数,那么则优先调用: class MyClass { public...{ MyClass obj{5, 1.0}; }; 我们可能期望MyClass obj{5, 1.0};调用第一个构造函数(以int和double作为参数构造函数),但由于存在以std::initializer_list...)默默执行,而开发人员则认为它正在使用第一个构造函数,emm,后果不堪设想~~ 在上面提了,编译器会优先调用参数std::initializer_list构造函数,但是有个例外: class MyClass

    21110

    【C++11特性篇】C++11中新增initializer_list——初始化小利器(2)

    return 0; } 二.std::initializer_list使用场景(初始化容器对象,作为operator=参数…) std::initializer_list一般是作为构造函数参数...C++11对STL中不少容器 (vector,list,map…) 就 增加std::initializer_list作为参数构造函数 ,这样初始化容器对象就更方便了 std::initializer_list...也可以作为operator=参数 ,这样就可以用大括号赋值 三.对比【C++11特性{ }隐式类型转换】&【调用initializer_listvector构造函数】不同原理 C++11中新增关于...{}用法 (传送门):具体对象是下面代码中Point, 直接调用两个参数构造 – 隐式类型转换 我们vector容器构造函数参数std::initializer_list, 这里是调用initializer_list...vector v1 = { 1,2,3,4,3}; // 调用initializer_listvector构造函数 Point p1 = { 1,1}; // 直接调用两个参数构造

    39010

    【重学 C++】06 | C++该不该使用 explicit

    单入参std::initializer_list构造函数std::initializer_list 是 C++11 中引入一种特殊类型,用于简化在初始化对象时传递初始化列表过程。...() {MyClass obj = {1, 2, 3, 4, 5}; // 使用初始化列表语法进行隐式转换}对于带有std::initializer_list类型参数构造函数,也不推荐使用explicit...因为使用std::initializer_list作为构造函数入参,就是为了方便初始化对象。...如果将MyClass构造函数标记为explicit,则在创建obj对象时,将需要显式地调用构造函数,MyClass obj({1, 2, 3, 4, 5});。...隐式转换可能导致精度丢失、调用目标函数混乱、对象被错误回收以及operator bool错误转换等问题。绝大多数情况下,我们都优先考虑禁止隐式转换。

    23900

    CC++开发基础——可变参数与可变参数模板

    在C++语言中,C++11标准提供了两种使用可变参数方式: 1.如果可变参数参数类型相同,可以使用标准库中initializer_list。...initializer_list参数可以使用迭代器来访问。 initializer_list实例中传入参数时需要使用{}把多个参数括起来。...std::cout << value << ", "; } //参数包中除了最后一个元素之外其他元素都会调用这个版本show_list template<typename T, typename....第一次递归调用print,传递实参:2,参数包剩余元素:3.14, "test" 第二次递归调用print,传递实参:3.14,参数包剩余元素:"test" 第三次递归调用print,传递实参...运算符来保证,在不重复定义同名函数情况下让递归退出。 "sizeof..."运算符可以判断参数包中元素数量。 退出递归方式: 判断当参数元素个数为零时,退出函数调用

    58150

    Effective Modern C++翻译(3)-条款2:明白auto类型推导

    cx类型 func_for_cx(x); // 概念上函数调用参数 // 推导出类型就是cx...(x); // 概念上函数调用参数 // 推导出类型就是rx类型 就像我说那样,auto...无法推导出std::initializer_list中T类型 就像注释里指出那样,类型推导在这种情况下失败了,但是,重要是认识到这里其实发生了两种形式类型推导,一种来源于auto使用...,x5类型需要被推导出来,另外因为auto是用大括号初始化式初始化,x5类型必须被推导为std::initializer_list,但是std::initializer_list是一个模板,所以实例化模板...一个变量被声明了,(2)它初始化是用大括号初始化式进行初始化(its initializer is inside braces),只有这种情况下,auto下被推导为std::initializer_list

    706100

    spdlog学习笔记

    logger格式: 设置模式字符串(推荐) set_pattern(pattern_string); 或者实现自定义格式器,实现formatter接口,并调用 set_formatter(std::make_shared...你应该判断智能指针有效性 注册新loggers 一般情况下没必要去注册loggers,因为它们已经自动注册了 手动创建loggers,需要自己去注册,使用 register_logger(std:...loggers被创建之前调用该函数 如果不同loggers必须要使用不同队列,那么可以创建不同线程池,并传递给loggers: auto tp = std::make_shared<details...如果你使用异步日志记录,一定要确保在main()函数退出时调用spdlog::shutdown()函数 Flush策略 ---- 默认情况下,spdlog允许底层libc在它认为合适时进行刷新,以获得良好性能...由一个单独工作线程定期调用每一个loggerflush()实现 下例中,对所有已注册loggers定期5秒调用flush(): spdlog::flush_every(std::chrono::seconds

    1.4K21

    深入解析C++auto自动类型推导

    ,而实际上我们并不关心它具体类型,std::map m; for (std::map::iterator it = m.begin...,如果我们要修改代码,就不用去修改相应类型,比如我们将一种容器类型改为另一种容器,迭代器类型不需要修改,std::map m = { ... }; auto...跨平台可移植性 假如你代码中定义了一个vector,然后想要获取vector元素大小,这时你调用了成员函数size来获取,此时应该定义一个什么类型变量来承接它返回值?...如下面的例子: auto sum = [](auto p1, auto p2) { return p1 + p2; }; 这样定义lambda式有点像是模板,调用sum时会根据传入参数推导出类型,你可以传入...lambda式参数无法使用initializer_list类型 同样地,在lambda式使用auto来声明形参时,也不能给它传递initializer_list类型参数,如下代码: std::vector

    27020

    C++11:构建多线程环境下资源管理器

    (size_t count,R start=0):resource_manager(make_vector(count,start)){} /* * std::vector类型资源数组为参数构造函数.../* * 使用初始化列表为参数构造函数 * */ resource_manager(std::initializer_list list):resource_manager...::make_shared(v.begin(), v.end());; } /* * 阻塞方式从队列中获取可用资源 * 资源数为...同一个线程多次调用acquire不会重复申请资源,只会将已经申请资源对应引用计数(lock_count)加1,同一个线程多次调用release不会重复释放资源,只会将已经申请资源对应引用计数(lock_count...resource_guard函数获取通道资源 // 资源申请和释放都已经被RAII对象自动完成了, // 这里调用代码只管调用get函数返回所要资源就行了,不用考虑资源申请和释放问题

    53010

    《C++Primer》第十六章 模板与泛型编程

    >()) { } // 接受一个initializer_list参数构造函数将其类型参数为T作为initializer_list参数元素类型 template Blob::Blob(std::initializer_list il) : data(std::make_shared>(il)) { } // 使用方法...,这种情况下,类和成员各自有自己、独立模板参数。...data(std::make_shared>(b, e)) { } 4.3 实例化与成员模板 为了实例化一个类模板成员模板,我们必须同时提供类和函数模板实参。...但是C++在正常绑定规则外定义了两个例外规则,允许这种绑定: 第一个例外规则:当我们将一个左值(i)传递给函数右值引用参数,且此右值引用指向模板类型参数T&&)时,编译器推断模板类型参数为实参左值引用类型

    1.9K10
    领券