简体   繁体   English

的std :: make_array <size_t> 来自signed int

[英]std::make_array<size_t> from signed int

Given a code: 给出一个代码:

constexpr auto a = std::make_array<size_t>(1, 2, 3);

Clang (3.7) with a realization copied from GCC's libstdc++v3 experimental/array gives this warning: Clang(3.7)从GCC的libstdc ++ v3实验/数组中复制了一个实现,给出了这个警告:

error: non-constant-expression cannot be narrowed from type 'int' to 'value_type' (aka 'unsigned long') in initializer list [-Wc++11-narrowing]
return {{ std::forward<Types>(t)... }};

Is this legal when a compiler knows at compile-time, that 1, 2 and 3 can be implicitly converted to size_t ? 当编译器在编译时知道这是否合法时,1,2和3可以隐式转换为size_t

It gives no warning when I write: 我写的时候没有警告:

constexpr std::array<size_t, 3> a{1, 2, 3};

And std::make_array is supposed to be the same as this construction. 并且std::make_array应该与此构造相同。

It is more theoretical than practical question. 它更具理论性而非实际性。

Bonus question: how can std::make_array be corrected in GCC's realization to accept code given above? 额外的问题:如何在GCC的实现中纠正std::make_array以接受上面给出的代码?

GCC's realization: 海湾合作委员会的实现:

template <typename _Dest = void, typename... _Types>
  constexpr auto
  make_array(_Types&&... __t)
    -> array<conditional_t<is_void_v<_Dest>,
                           common_type_t<_Types...>,
                           _Dest>,
             sizeof...(_Types)>
  {
    static_assert(__or_<
                  __not_<is_void<_Dest>>,
                  __and_<__not_<__is_reference_wrapper<decay_t<_Types>>>...>>
                  ::value,
                  "make_array cannot be used without an explicit target type "
                  "if any of the types given is a reference_wrapper");
    return {{forward<_Types>(__t)...}};
  }

No, std::make_array is not supposed to be the same as that construction. 不, std::make_array不应该和那个结构一样。

std::make_array takes Types&&... , which requires determining the types from the arguments, and in your case produces parameters of type int . std::make_array采用Types&&... ,这需要从参数中确定类型,并在您的情况下生成int类型的参数。 Inside make_array , you no longer have constant values, so the exception that in-range constant integer values can be converted inside {} no longer applies. make_array ,您不再具有常量值,因此可以在{}内转换范围内常量整数值的异常不再适用。

A different example is std::array<void*, 1>{0} vs. std::make_array<void*>(0) . 另一个例子是std::array<void*, 1>{0} std::make_array<void*>(0) The former is valid, since 0 is convertible to any pointer type. 前者是有效的,因为0可以转换为任何指针类型。 The latter is invalid, since an integer parameter which happens to have the value 0 is not implicitly convertible to any pointer type. 后者无效,因为碰巧具有值0的整数参数不能隐式转换为任何指针类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM