initializer_list 类

飞翔的薄荷 2014-06-15 08:28:07
代码 initializer_list<int> a = { 10, 11, 12 }; 可以编译通过。
我想 如何自己实现 CMyClass<int> a = { 10, 11, 12 }; 也可以编译通过。

参考了 initializer_list的实现,拷贝代码 CMyClass却没法实现这样的语句: CMyClass<int> a = { 10, 11, 12 };

initializer_list的代码如下:

#pragma once
#ifndef _INITIALIZER_LIST_
#define _INITIALIZER_LIST_
#ifndef RC_INVOKED
#include <cstddef>

#pragma pack(push,_CRT_PACKING)
#pragma warning(push,3)
#pragma push_macro("new")
#undef new

_STD_BEGIN
// TEMPLATE CLASS initializer_list
template<class _Elem>
class initializer_list
{ // list of pointers to elements
public:
typedef _Elem value_type;
typedef const _Elem& reference;
typedef const _Elem& const_reference;
typedef size_t size_type;

typedef const _Elem* iterator;
typedef const _Elem* const_iterator;

initializer_list() _NOEXCEPT
: _First(0), _Last(0)
{ // empty list
}

initializer_list(const _Elem *_First_arg,
const _Elem *_Last_arg) _NOEXCEPT
: _First(_First_arg), _Last(_Last_arg)
{ // construct with pointers
}

const _Elem *begin() const _NOEXCEPT
{ // get beginning of list
return (_First);
}

const _Elem *end() const _NOEXCEPT
{ // get end of list
return (_Last);
}

size_t size() const _NOEXCEPT
{ // get length of list
return ((size_t)(_Last - _First));
}

private:
const _Elem *_First;
const _Elem *_Last;
};

// TEMPLATE FUNCTION begin
template<class _Elem> inline
const _Elem *begin(initializer_list<_Elem> _Ilist) _NOEXCEPT
{ // get beginning of sequence
return (_Ilist.begin());
}

// TEMPLATE FUNCTION end
template<class _Elem> inline
const _Elem *end(initializer_list<_Elem> _Ilist) _NOEXCEPT
{ // get end of sequence
return (_Ilist.end());
}
_STD_END

#pragma pop_macro("new")
#pragma warning(pop)
#pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _INITIALIZER_LIST_ */


这个是vs2013 initializer_list类的实现代码

自己的类

template<class _Elem>
class CMyClass
{ // list of pointers to elements
public:
typedef _Elem value_type;
typedef const _Elem& reference;
typedef const _Elem& const_reference;
typedef size_t size_type;

typedef const _Elem* iterator;
typedef const _Elem* const_iterator;

CMyClass() _NOEXCEPT
: _First(0), _Last(0)
{ // empty list
}

CMyClass(const _Elem *_First_arg,
const _Elem *_Last_arg) _NOEXCEPT
: _First(_First_arg), _Last(_Last_arg)
{ // construct with pointers
}

const _Elem *begin() const _NOEXCEPT
{ // get beginning of list
return (_First);
}

const _Elem *end() const _NOEXCEPT
{ // get end of list
return (_Last);
}

size_t size() const _NOEXCEPT
{ // get length of list
return ((size_t)(_Last - _First));
}

private:
const _Elem *_First;
const _Elem *_Last;
};

// TEMPLATE FUNCTION begin
template<class _Elem> inline
const _Elem *begin(CMyClass<_Elem> _Ilist) _NOEXCEPT
{ // get beginning of sequence
return (_Ilist.begin());
}

// TEMPLATE FUNCTION end
template<class _Elem> inline
const _Elem *end(CMyClass<_Elem> _Ilist) _NOEXCEPT
{ // get end of sequence
return (_Ilist.end());
}


相同的代码无法实现相同的功能,不知为何。
...全文
1064 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2016-06-09
  • 打赏
  • 举报
回复
nullptr_t dynamic_cast 可以自己实现,当然要换个名字 initializer_list 不可以自己实现,就像引用一样不可以自己实现 你可以实现一个类,有引用的部分功能,还能顺便研究一下。编译器如何实现引用的 但是你永远也不能自行实现一个 不利用 C++引用,而实现和C++引用 相同的 自定义类型 initializer_list 中,有一部分是需要编译器全面支持,才能用的功能,这个不能自行实现 operator new,operator delete 也是一样 有些东西,必须编译器支持,才能做好 C++采取的策略是, 一部分在编译器上直接实现(这部分是不能修改的), 另一部分在库中实现(这部分你可以自行实现一个类似的东东), 分工合作 C++引用则是语言的一部分, 你是全面模仿不了的, 只能部分模仿一下
几罗星人 2015-06-08
  • 打赏
  • 举报
回复
回答CMyClass(std::initializer_list<T> list)的其实都没懂楼主的意思,楼主的目的不是为了是自己的类可以拥有 CMyClass<int> a = { 10, 11, 12 };这样的初始化语法,其根本的目的就是要自己做一个initializer_list类,或者说,让别人的类能够用这个CMyClass来实现初始化列表的语法,例如: template <class T> class AAA { public: AAA(CMyClass list); } 这个AAA类一样有AAA<int> CAAA = { 10, 11, 12 };这样的初始化语法。 用四个形容就是“谋朝篡位”,自己写的类具有与initializer_list一样的能力,达到能取代他的效果。 然后说一下我自己的体会,楼主做过的事我也做过,一样失败了,估计确实像二楼说的,这是编译器开挂的一个东西。
whitespace 2015-03-02
  • 打赏
  • 举报
回复
template <class T> class CMyClass { public: CMyClass(std::initializer_list<T> list) { } }; CMyClass<int> a = { 1, 2, 3 }; // vs2013编译通过
ligand 2014-12-21
  • 打赏
  • 举报
回复
楼主没想明白的地方在于: initializer_list<int> a = { 10, 11, 12 }; 可以编译通过。 根据C++11标准,花括号围起来的初始化器列表,将被自动隐式构造为一个initializer_list的模板类对象。然后,再默认使用initializer_list的缺省拷贝构造函数,给声明的对象a初始化。当然,上述过程也可被编译器执行一次优化,省略了拷贝构造函数。 相反, 如何自己实现 CMyClass<int> a = { 10, 11, 12 }; 也可以编译通过? 这显而易见——需要用一个initializer_list的模板类对象去构造一个CMyClass<int>对象。 这一步是没有缺省实现的(构造函数)! 四楼已经给出了解决办法。
ri_aje 2014-06-16
  • 打赏
  • 举报
回复
CMyClass 需要定义接收 initializer_list 的构造函数。
飞翔的薄荷 2014-06-16
  • 打赏
  • 举报
回复
估计1楼的答案靠谱些
飞翔的薄荷 2014-06-16
  • 打赏
  • 举报
回复
引用 3 楼 ri_aje 的回复:
CMyClass 需要定义接收 initializer_list 的构造函数。
引用 4 楼 NineTyNine_LP 的回复:
使用initializer_list作为构造函数参数即可。、
3楼4楼估计,没懂我的意思。我的意思是既然initializer_lis是个类,那么同样的代码也能实现initializer_lis的功能。 结果却不可以。
-LanPei- 2014-06-16
  • 打赏
  • 举报
回复
对了,这时C++11才支持的。记得在编译命令后添加--std=c++11
-LanPei- 2014-06-16
  • 打赏
  • 举报
回复
使用initializer_list作为构造函数参数即可。、

class A{
    public:
    A(initializer_list<string> il):vec(il){}
    
    private:
    vector<string> vec;
};


A a={"a","b"};

taodm 2014-06-15
  • 打赏
  • 举报
回复
有一些东西是编译器作弊的。
unituniverse2 2014-06-15
  • 打赏
  • 举报
回复
1。initializer_list是标准要求编译器支持的功能。而initializer_list在库文件中仅仅提供解析initializer_list的实现部分。和普通的类不同,initializer_list是编译器内置的。 比如常用的有这么几个符号是编译器内置的(不完全,仅列一部分): __VAR_ARGS__ dynamic_cast typeid nullptr_t initializer_list ... 2。如果想自己的类提供初始化列表的功能,可以加入一个参数是initializer_list的构造函数。

64,676

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧