どうすればa3
コンパイルしますか?
int main()
{
int a1[] = { 1, 2, 3 };
std::array<int, 3> a2 = { 1, 2, 3 };
std::array<int> a3 = { 1, 2, 3 };
}
初期化リスト、特に長いリストを使用する場合、配列のサイズをハードコーディングするのは非常に不便で、脆弱です。回避策はありますか?そうでなければ、Cの配列とstd::array
は、代替となるはずです。
現在のところ、独自のmake_array
、これについての提案があります N3824:make_array 次のスコープがあります:
LWG 851は、代替構文を提供することを目的としています
array<T, N> a = { E1, E2, ... };
、したがって、次の
auto a = make_array(42u, 3.14);
整形式です(内部に追加のstatic_castsが適用されています)
array<double, 2> = { 42u, 3.14 };
整形式です。
このペーパーでは、タプルの観点とアレイの観点の両方から包括的なstd :: array作成インターフェイスのセットを提供することを目的としているため、ナローイングは当然禁止されています。設計の決定で、この方向に基づいた詳細を参照してください。
また、 サンプル実装 も含まれます。これはかなり長いため、ここでコピーすることは実用的ではありませんが、Konrad Rudolphには上記のサンプル実装と一致する簡易バージョン here があります。
template <typename... T>
constexpr auto make_array(T&&... values) ->
std::array<
typename std::decay<
typename std::common_type<T...>::type>::type,
sizeof...(T)> {
return std::array<
typename std::decay<
typename std::common_type<T...>::type>::type,
sizeof...(T)>{std::forward<T>(values)...};
}
「このような恐ろしく複雑な(私にとって)機能が必要です」と言うとき、あなたは少し過激になります。自分で簡易バージョンを作成できます。提案には、C配列を変換し、最初のパラメーターから型を推定する「to_array」関数も含まれています。それを省くと、かなり管理しやすくなります。
template<typename T, typename... N>
auto my_make_array(N&&... args) -> std::array<T,sizeof...(args)>
{
return {std::forward<N>(args)...};
}
あなたはその後、のように呼び出すことができます
auto arr = my_make_array<int>(1,2,3,4,5);
編集:私が見落とした提案には実際にそのバージョンがあることに言及する必要があるので、これは私のバージョンよりも正しいはずです:
template <typename V, typename... T>
constexpr auto array_of(T&&... t)
-> std::array < V, sizeof...(T) >
{
return {{ std::forward<T>(t)... }};
}