8

Suppose I have an array of:

std::array<int, 6> {4,3,2};

Is it possible to raise an error or warning when this is the case? In some cases it might be useful to have this explicitly matching.

Marnix
  • 6,384
  • 4
  • 43
  • 78
  • That should work like initializing a "normal" C-style plain array: The remaining values are "zero" initialized. So there's really nothing wrong with it. – Some programmer dude Aug 16 '19 at 11:53
  • 4
    My worries are mainly people initializing a wrong sized array and forgetting a number. I understand that the code is in no case wrong, only that there might be cases where you have a long array that you want to do some static assertion in a way to see if it is missing values. – Marnix Aug 16 '19 at 11:57
  • you could create your own `init_with_all_elements` function, though then still nothing prevents you from calling the arrays constructor directly – 463035818_is_not_an_ai Aug 16 '19 at 11:59

3 Answers3

10

You can use std::make_array or something like it to cause the types to differ

std::array<int, 6> = std::make_array(4,3,2);

gives this error in gcc:

<source>:30:53: error: conversion from 'array<[...],3>' to non-scalar type 'array<[...],6>' requested

PeterT
  • 7,981
  • 1
  • 26
  • 34
8

You can create your own layer of abstraction that complains when you don't pass the exact same number of arguments for initialization.

template <std::size_t N, class ...Args>
auto createArray(Args&&... values)
{
   static_assert(sizeof...(values) == N);

   using First = std::tuple_element_t<0, std::tuple<Args...>>;

   return std::array<First, N>{values...};
}

To be invoked as

auto ok = createArray<6>(4, 3, 2, 1, 0, -1);

auto notOk = createArray<6>(4, 3, 2};
lubgr
  • 37,368
  • 3
  • 66
  • 117
5

Instead of writing your own createArray method you can use the https://en.cppreference.com/w/cpp/experimental/make_array

if your compiler supports it.

#include <experimental/array>
int main()
{
    std::array<int,5> arr1= std::experimental::make_array(1, 2, 3, 4, 5); // ok
    std::array<int,3> arr2= std::experimental::make_array(1, 2, 3, 4, 5); // fails
    std::array<int,6> arr3= std::experimental::make_array(1, 2, 3, 4, 5); // fails
}

But everybody can directly init the array via constructor. So there is no guarantee for your code base if you don't check ( automatically ) against some coding guidelines.

Klaus
  • 24,205
  • 7
  • 58
  • 113