2017-01-22 27 views
1

給定一個代碼:的std :: make_array <size_t>從符號整數

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

鏘(3.7)與海灣合作委員會的libstdc++v3 experimental/array複製一個實現給出了這樣的警告:

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)... }}; 

這是合法的,當一個編譯器在編譯時知道,1,2和3可以隱式轉換爲size_t

它給我寫任何警告:

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

而且std::make_array應該是與此相同的結構。

這是比實際問題更理論。

紅利問題:std::make_array如何糾正GCC的實現接受上面給出的代碼?

GCC的實現:

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)...}}; 
    } 

回答

3

不,std::make_array不應該是相同的結構。

std::make_array需要Types&&...,它需要從參數中確定類型,並在你的情況下產生int類型的參數。在make_array內部,您不再具有常數值,因此{}內的範圍內常量整數值可以轉換的異常不再適用。

不同的示例是std::array<void*, 1>{0}std::make_array<void*>(0)。前者是有效的,因爲0可以轉換爲任何指針類型。後者是無效的,因爲恰好具有值0的整數參數不能隱式轉換爲任何指針類型。

+1

它是由標準規定的,還是實現的結果? – vladon

+0

@vladon這是[此提案添加它]所必需的(http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4391.html),但我不確定是否這是最新的描述。 – hvd

+1

如果有幫助,目前的措辭來自[N4617](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4617.pdf)§9.2.2和[P0325] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0325r1.html)。 – ildjarn

相關問題