C ++ 11可以构造一个std :: initializer_list吗? [英] C++11 is it possible to construct an std::initializer_list?

查看:98
本文介绍了C ++ 11可以构造一个std :: initializer_list吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用std::discrete_distribution的类,该类可以使用std::initializer_list或几个迭代器.我的课程在某些方面包装了discrete_distribution,因此我真的很想模仿接受std::initializer_list的能力,然后将其传递下来.

这很简单.

但是,std::initializer_list将始终通过一些未知值构造.因此,如果它只是一个std::discrete_distribution,我只是从某个容器的迭代器构造而成.但是,为了让我可以通过我的类使用该类,我需要为Iterator类型的类模板化.

我不想对我的类进行模板化,因为它只是偶尔会使用initializer_list,而在不使用它的情况下,它会使用std::uniform_int_distribution作为模板参数,这可能会造成混淆.

我知道我可以默认使用template参数,并且我知道我可以只定义vector::iterator.我宁愿不这样做.

解决方案

根据文档, std :: initializer_list 不能在标准C ++中非空构造.顺便说一句,对于C stdarg(3) va_list(并且可能出于类似的原因,因为可变参数函数的传递是特定于实现的,并且通常具有自己的 ABI 特殊性;不过请参见 libffi ).

GCC 中,std::initializer_list是C ++编译器的已知(同样,<stdarg.h>使用C编译器提供的一些内置功能),并且具有特殊的支持.

C ++ 11标准(更确切地说,其

如果您的类有一个接受std::initializer_list<int>的构造函数,则它可能应该有另一个接受std::vector<int>std::list<int>的构造函数(或者,如果您有一些可交换性,则可能是std::set<int>),那么您不需要使用一些奇怪的模板迭代器.顺便说一句,如果您需要迭代器,则可以对构造函数进行模板化,而不是对整个类进行模板化.

I have a class that's using an std::discrete_distribution which can take an std::initializer_list OR a couple of iterators. My class is in some ways wrapping the discrete_distribution so I really wanted to mimic the ability to take an std::initializer_list which would then be passed down.

This is simple.

However, the std::initializer_list will always be constructed through some unknown values. So, if it was just a std::discrete_distribution I would just construct from iterators of some container. However, for me to make that available via my class, I would need to templatize the class for the Iterator type.

I don't want to template my class because it's only occasionally that it would use the initializer_list, and the cases where it doesn't, it uses an std::uniform_int_distribution which would make this template argument, maybe confusing.

I know I can default the template argument, and I know that I could just define only vector::iterators if I wanted; I'd just rather not.

解决方案

According to the documentation, std::initializer_list cannot be non-empty constructed in standard C++. BTW, it is the same for C stdarg(3) va_list (and probably for similar reasons, because variadic function argument passing is implementation specific and generally has its own ABI peculiarities; see however libffi).

In GCC, std::initializer_list is somehow known to the C++ compiler (likewise <stdarg.h> uses some builtin things from the C compiler), and has special support.

The C++11 standard (more exactly its n3337 draft, which is almost exactly the same) says in §18.9.1 that std::initializer_list has only an empty constructor and refers to §8.5.4 list-initialization

You probably should use std::vector and its iterators in your case.

As a rule of thumb and intuitively, std::initializer_list is useful for compile-time known argument lists, and if you want to handle run-time known arguments (with the "number" of "arguments" unknown at compile time) you should provide a constructor for that case (either taking some iterators, or some container, as arguments).

If your class has a constructor accepting std::initializer_list<int> it probably should have another constructor accepting std::vector<int> or std::list<int> (or perhaps std::set<int> if you have some commutativity), then you don't need some weird templates on iterators. BTW, if you want iterators, you would templatize the constructor, not the entire class.

这篇关于C ++ 11可以构造一个std :: initializer_list吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆