C++ C++;具有常量初始值设定项列表的对象数组
我有一些这样的代码:C++ C++;具有常量初始值设定项列表的对象数组,c++,C++,我有一些这样的代码: class MyObject { private: int x; public: MyObject(int x) : x(x) {} }; 我想初始化5个MyObject实例。我知道我可以用g++8.3.0做到这一点 MyObject obj_array[5]{1, 2, 3, 4, 5}; 但是,我无法做到这一点: const int myInts[5] = {1, 2, 3, 4, 5}; MyObject obj_array[5](myIn
class MyObject {
private:
int x;
public:
MyObject(int x) : x(x) {}
};
我想初始化5个MyObject
实例。我知道我可以用g++8.3.0做到这一点
MyObject obj_array[5]{1, 2, 3, 4, 5};
但是,我无法做到这一点:
const int myInts[5] = {1, 2, 3, 4, 5};
MyObject obj_array[5](myInts);
是否有任何方法可以使第二个初始化方法(使用const integer array初始化列表构造函数初始化对象数组)工作?问题在于,我们有一个特殊的编译器框架,不允许动态内存或大多数STL数据类型,如
vector
不漂亮,但这似乎是可行的:
const int myInts[5] = { 1, 2, 3, 4, 5 };
MyObject obj_array[5] = {myInts[0], myInts[1], myInts[2], myInts[3], myInts[4]};
如果我们正在开发丑陋的解决方案,这里有一个具有可扩展性的解决方案:
#define LIST { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
const int myInts[] = LIST;
MyObject obj_array[] = LIST;
#undef LIST
不是这样,因为当原始数组类型使用少于其表达式计数的表达式初始化时,对象会得到默认初始化 但您可以做的一件事是创建自己的类似数组的类模板:
#include <cstddef>
#include <type_traits>
#include <initializer_list>
#include <utility>
#include <iterator>
template <std::size_t N>
class MyObjectArray
{
public:
using array_type = MyObject[N];
template <typename T, typename Enable =
std::enable_if_t<std::is_convertible_v<T, int>>>
MyObjectArray(T (&arr)[N]);
template <typename T = int, typename Enable =
std::enable_if_t<std::is_convertible_v<T, int>>>
MyObjectArray(std::initializer_list<T> il);
template <typename InputIter, typename Enable =
std::enable_if_t<std::is_convertible_v<
typename std::iterator_traits<InputIter>::reference, int>>>
MyObjectArray(InputIter start, InputIter end);
operator array_type& () noexcept { return m_array; }
operator const array_type& () const noexcept { return m_array; }
private:
template <std::size_t... I, typename InputIter>
MyObjectArray(std::index_sequence<I...>, InputIter iter)
: m_array{ (static_cast<void>(I), *iter++) ... } {}
static std::make_index_sequence<N> check_count(std::size_t n) {
if (n != N)
throw std::invalid_argument(
"Incorrect number of elements initializing MyObjectArray");
// Or if exceptions not supported, some other error reporting
// mechanism and abort.
return {};
}
MyObject m_array[N];
};
template <std::size_t N>
template <typename T, typename Enable>
MyObjectArray<N>::MyObjectArray(T (&arr)[N])
: MyObjectArray(std::make_index_sequence<N>{}, arr) {}
template <std::size_t N>
template <typename T, typename Enable>
MyObjectArray<N>::MyObjectArray(std::initializer_list<T> il)
: MyObjectArray(check_count(il.size()), il.begin()) {}
template <std::size_t N>
template <typename InputIter, typename Enable>
MyObjectArray<N>::MyObjectArray(InputIter start, InputIter end)
: MyObjectArray(check_count(std::distance(start, end)), start) {}
#包括
#包括
#包括
#包括
#包括
模板
类MyObjectArray
{
公众:
使用数组_type=MyObject[N];
模板
MyObjectArray(T&arr)[N]);
模板
MyObjectArray(std::initializer\u list il);
模板>
MyObjectArray(输入端开始,输入端结束);
运算符数组_type&()noexcept{return m_数组;}
运算符const数组_type&()const noexcept{return m_数组;}
私人:
模板
MyObjectArray(std::InputIter iter索引_序列)
:m_数组{(静态_cast(I),*iter++)…}{}
静态标准::生成索引\u顺序检查\u计数(标准::大小\u t n){
如果(n!=n)
抛出std::无效的_参数(
“初始化MyObjectArray的元素数不正确”);
//或者,如果不支持异常,则执行其他一些错误报告
//机制和中止。
返回{};
}
MyObject m_数组[N];
};
模板
模板
MyObjectArray::MyObjectArray(T(&arr)[N])
:MyObjectArray(std::make_index_sequence{},arr{}
模板
模板
MyObjectArray::MyObjectArray(std::初始值设定项\u列表il)
:MyObjectArray(检查计数(il.size()),il.begin()){}
模板
模板
MyObjectArray::MyObjectArray(输入程序开始,输入程序结束)
:MyObjectArray(检查计数(标准::距离(开始,结束)),开始){
这可以像这样使用:
int main()
{
const int myInts[5] = {1, 2, 3, 4, 5};
MyObjectArray obj_array(myInts);
MyObjectArray<5> a2 = {3, 4, 5, 6, 7};
}
intmain()
{
常量int myInts[5]={1,2,3,4,5};
MyObjectArray obj_阵列(myInts);
MyObjectArray a2={3,4,5,6,7};
}
请参阅。只需使用
std::array
(或boost::array
,或您自己的变体)。它不会动态分配任何内容。您是否需要所需的初始化语法?是否可以使用std::array
?另外,您可以使用什么语言标准(03,11,14,17)?std::array
也不允许。(高度专有的)编译器允许C++11的子集,但没有动态内存,没有递归,没有STL数据类型,没有超越函数,等等。啊,这太棒了!这和我想要的非常接近。重复可能隐藏在Boost中。预处理器技巧也一样。这实际上比@selbie的原始解决方案好一点。谢谢你的代码片段。