std::initializer_list<int const> 不能从 std::initializer_list<int> 构造
std::initializer_list<int const> cannot be constructed from std::initializer_list<int>
我的问题是 std::initializer_list
类型之间缺乏转换,其中包含的类型或多或少是 cv 合格的,而这些转换似乎很容易实现。
考虑以下无效代码:
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!
我假定 语言规范要求默认为std::initializer_list<U>
推导非 cv 合格的 U
。
据我所知,具有 std::initializer_list
构造函数重载的 std::optional
(以及 std::any
和 std::variant
)的全部意义在于避免指定确切的类型初始化列表。要编译上述代码的第二行,这正是您必须做的。
std::initializer_list
已经拥有一个 const*
到它的数据(无论如何在 libc++
中)。我没有理由看到上面的代码不起作用?这是语言中可以解决的问题,还是我遗漏了什么?
听起来你的问题是为什么 std::initializer_list<T const>
不能从 std::initializer_list<T>
构造,尽管实现这样的转换很容易。
我认为答案是您首先不应该拥有 std::initializer_list<T const>
,因为正如您指出的那样,std::initializer_list<T>
只允许 const
访问其元素无论如何。
因此可以说 C++ 中有一个 "cultural norm",您不应该有任何需要 std::initializer_list<T const>
参数的构造函数。例如,标准库容器的 None 会这样做,因为 cv 限定的值类型无论如何都是非法的(除了 std::array
的情况,当然,它无论如何都没有用户定义的构造函数) .
如果你自己写的类型MyContainer
支持MyContainer<T const>
,那我建议你做成下面这样:
template <class T>
class MyContainer {
public:
MyContainer(std::initializer_list<std::remove_cv_t<T>> il);
// ...
};
我的问题是 std::initializer_list
类型之间缺乏转换,其中包含的类型或多或少是 cv 合格的,而这些转换似乎很容易实现。
考虑以下无效代码:
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!
我假定 语言规范要求默认为std::initializer_list<U>
推导非 cv 合格的 U
。
据我所知,具有 std::initializer_list
构造函数重载的 std::optional
(以及 std::any
和 std::variant
)的全部意义在于避免指定确切的类型初始化列表。要编译上述代码的第二行,这正是您必须做的。
std::initializer_list
已经拥有一个 const*
到它的数据(无论如何在 libc++
中)。我没有理由看到上面的代码不起作用?这是语言中可以解决的问题,还是我遗漏了什么?
听起来你的问题是为什么 std::initializer_list<T const>
不能从 std::initializer_list<T>
构造,尽管实现这样的转换很容易。
我认为答案是您首先不应该拥有 std::initializer_list<T const>
,因为正如您指出的那样,std::initializer_list<T>
只允许 const
访问其元素无论如何。
因此可以说 C++ 中有一个 "cultural norm",您不应该有任何需要 std::initializer_list<T const>
参数的构造函数。例如,标准库容器的 None 会这样做,因为 cv 限定的值类型无论如何都是非法的(除了 std::array
的情况,当然,它无论如何都没有用户定义的构造函数) .
如果你自己写的类型MyContainer
支持MyContainer<T const>
,那我建议你做成下面这样:
template <class T>
class MyContainer {
public:
MyContainer(std::initializer_list<std::remove_cv_t<T>> il);
// ...
};