c++ - 大括号初始值设定项列表推导指南
问题描述
有一个非常类似于std::initializer_list
在标准 C++ 库不可用的环境中使用的实现:
template<typename T>
class initializer_list {
public:
using value_type = T;
using reference = const T &;
using const_reference = const T &;
using size_type = size_t;
using iterator = const T *;
using const_iterator = const T *;
private:
iterator m_array;
size_type m_length;
constexpr initializer_list( const_iterator array, size_type length ) noexcept : m_array( array ), m_length( length ) {}
public:
constexpr initializer_list( void ) noexcept : m_array( nullptr ), m_length( 0 ) {}
/* Number of elements */
constexpr size_type size( void ) const noexcept {
return m_length;
}
/* First element */
constexpr const_iterator begin( void ) const noexcept {
return m_array;
}
/* One past the last element */
constexpr const_iterator end( void ) const noexcept {
return begin() + size();
}
};
template<typename T>
constexpr const T * begin( initializer_list<T> list ) noexcept {
return list.begin();
}
template<typename T>
constexpr const T * end( initializer_list<T> list ) noexcept {
return list.end();
}
然后这样initializer_list<T>
将在另一个类构造函数中使用:
template<typename T>
struct user {
user( initializer_list<T> init_values ) { ... }
};
以及同时使用这两种东西的意图:
user<int> sample { 1, 2, 3, 4, 5 };
显然,编译器不知道如何推断大括号初始值设定项列表的类型,以便它使用上面实现的 initializer_list。我想应该实现某种演绎指南来连接我的 initializer_list 和大括号初始化列表的实现。但我不知道如何实施。
有人可以建议我如何实施所描述的扣除指南吗?
解决方案
在标准 C++ 库不可用的环境中
哪有这回事。虽然独立的 C++ 实现可以自由地仅实现标准库的一部分,但所有有效的 C++ 实现都必须提供一些组件。std::initializer_list
是这些组成部分之一。
因此,如果您拥有有效的 C++11 或更高版本的 C++ 实现,那么您必须拥有<initializer_list>
标头及其内容。这不是可选的。如果您的实现没有提供一个,那么它是有缺陷的。
它不是可选的原因是它的重要功能std::initializer_list
(即,它从一个花括号初始化列表生成)是 C++语言的函数,而不是库的函数。也就是说,编译器之外的代码不可能使{}
语法结构成为与行为方式完全相同的类型std::initializer_list
。
考虑您的代码:
user<int> sample { 1, 2, 3, 4, 5 };
如果你仔细想想,这应该意味着user<int>
将调用一个带有 5 个参数的构造函数。user
毕竟,如果有一个包含 5 个整数参数的构造函数,这就是它的意思。但这不是您想要的意思,对于vector<int>
. 为什么?
因为 C++ 的语言有一个关于列表初始化的特殊规则,它检测构造函数的存在,该构造函数接受std::initializer_list
与括号初始化列表类型匹配的 a,然后创建 astd::initializer_list
以传递给此构造函数。该规则的关键在于构造函数的存在,该构造函数接受std::initializer_list
并且没有其他类型。
您的代码不起作用,不是因为缺乏演绎指南,而是因为您的initializer_list
类型就语言而言没有特殊规则。
您无法使用用户定义的类型重新创建此语言行为。就像你不能让typeid
return 类型不是std::type_info
. 就像你不能做出enum class byte: unsigned char{};
与std::byte
.
推荐阅读
- javascript - 数组列表在线显示来自json的一个结果
- r - 循环或应用函数以运行具有不同变量的方程
- node.js - 如何在不重新启动进程(NodeJS)的情况下更新进程中的 ENV 变量?
- c - 字符串终止符问题
- r - 如何针对 R 中的分析变量绘制分类变量的条形图
- python - Django上传excel文件,用pandas处理,下载为csv
- html - 将 FlexBoxed Div 并排放置
- vb.net - 我应该如何为我的两因素身份验证系统生成“秘密”代码?
- c++ - 如何在带有向量的 C++ 中正确使用 FFTW?
- css - 如何在具有固定宽度和溢出设置为自动的 Div 中永远不会有换行