我一直在研究initializer_list
是如何实现的,所以我找到了该标准的18.9节,并找到了一个看起来足够简单的接口。我认为制作我自己的版本(我将其命名为MyNamespace::InitializerList
)和一个用例会很有启发性:
template<class T>
class ArrayPrinter
{
public:
ArrayPrinter(MyNamespace::InitializerList<T> list)
{
for (auto i : list) cout << i << endl;
}
};
...
ArrayPrinter ap{ {1,2,3} };
我惊讶地发现这不起作用,编译器抱怨说它找不到合适的构造函数(它想给我3个参数,但18.9节只描述了一个默认构造函数)。
经过一些修改之后,我发现我的类必须准确地命名为std::initializer_list
才能工作。我也可以在MyNamespace
中使用std::initializer_list
别名,但不能将MyNamespace::InitializerList
别名为std::initializer_list
。
看起来这并不是真正的language feature as it depends on the standard library
我的问题的要点是为什么名称如此重要,以及它试图传递给构造函数的3个参数是什么?
发布于 2013-08-11 05:11:50
这个名字很重要,因为标准说它很重要。这个标准需要某种方式让你能够说,“这个构造函数可以传递一个包含T类型的值序列的带括号的初始化列表”。这种方式被命名为"std::initializer_list
“。
您不能创建具有initializer_list
的所有语言属性的类。您可以创建一个满足标准initializer.list.syn部分指定类型的条件。但是您会注意到,在那里指定的唯一构造函数是一个默认构造函数。创建包含实际元素的initializer_list
的唯一方法依赖于编译器,而不是用户端代码。
所以你不能复制所有关于initializer_list
的东西。就像你无法复制std::type_info
一样。C++标准库不是可选的。
发布于 2020-07-10 17:54:59
这个答案并不完全准确。创建一个全功能的std::initializer_list
是可能的--它只需要满足目标编译器的特定需求。
对于GCC和克朗来说,这个要求是私人的。下面是libc++的实现(碰巧在GCC 8.3中也能正常工作):
template<class _Ep>
class initializer_list
{
const _Ep* __begin_;
size_t __size_;
inline
constexpr
initializer_list(const _Ep* __b, size_t __s) noexcept
: __begin_(__b),
__size_(__s)
{}
public:
typedef _Ep value_type;
typedef const _Ep& reference;
typedef const _Ep& const_reference;
typedef size_t size_type;
typedef const _Ep* iterator;
typedef const _Ep* const_iterator;
inline
constexpr
initializer_list() noexcept : __begin_(nullptr), __size_(0) {}
inline
constexpr
size_t size() const noexcept {return __size_;}
inline
constexpr
const _Ep* begin() const noexcept {return __begin_;}
inline
constexpr
const _Ep* end() const noexcept {return __begin_ + __size_;}
};
template<class _Ep>
inline
constexpr
const _Ep*
begin(initializer_list<_Ep> __il) noexcept
{
return __il.begin();
}
template<class _Ep>
inline
constexpr
const _Ep*
end(initializer_list<_Ep> __il) noexcept
{
return __il.end();
}
https://stackoverflow.com/questions/18164353
复制相似问题