无法从std :: initializer_list <int>

时间:2017-01-10 03:16:07

标签: c++ initializer-list c++17

我的问题是std::initializer_list类型之间缺少转换,当这些转换看起来很容易可行时,所包含的类型或多或少是合格的。

请考虑以下无效代码:

std::initializer_list<int> x{1,2,3,4,5,6};
std::initializer_list<int const> y = x; // error! cannot convert!

现在考虑std::optional并忽略荒谬的类型:

std::optional<std::vector<int>> x{std::in_place, {1,2,3,4,5}}; // OK
std::optional<std::vector<int const>> y{std::in_place, {1,2,3,4,5}}; // error!

假设语言规范要求默认情况下为U推断非cv限定std::initializer_list<U>

据我所知,具有std::optional构造函数重载的std::any(以及std::variantstd::initializer_list)的重点是避免指定确切的类型初始化列表。要获得上述代码的第二行进行编译,这正是您必须要做的。

std::initializer_list已经拥有const*的数据(无论如何都在libc++中)。我没有理由看到上面的代码无法工作?这是语言中可解决的问题,还是我错过了什么?

1 个答案:

答案 0 :(得分:4)

听起来您的问题是为什么std::initializer_list<T const>无法从std::initializer_list<T>构建,尽管实现这样的转换很容易。

我认为答案是你不应该首先拥有std::initializer_list<T const>,因为正如你所指出的那样,std::initializer_list<T>只允许const访问其元素。

因此可以说有一个&#34;文化规范&#34;在C ++中,您不应该有任何需要std::initializer_list<T const>参数的构造函数。例如,没有标准库容器可以执行,因为无论如何cv限定值类型都是非法的(std::array除外,当然,它没有用户定义的构造函数)。

如果您编写支持MyContainer的自己的MyContainer<T const>类型,那么我建议您将其设为如下所示:

template <class T>
class MyContainer {
  public:
    MyContainer(std::initializer_list<std::remove_cv_t<T>> il);
    // ...
};