我的问题是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::variant
和std::initializer_list
)的重点是避免指定确切的类型初始化列表。要获得上述代码的第二行进行编译,这正是您必须要做的。
std::initializer_list
已经拥有const*
的数据(无论如何都在libc++
中)。我没有理由看到上面的代码无法工作?这是语言中可解决的问题,还是我错过了什么?
答案 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);
// ...
};