StaticVector and StaticMatrix std::initializer_list::size validation at compile time

Issue #324 wontfix
Matthias Moulin created an issue

StaticVector and StaticMatrix have known sizes at compile-time. Currently, their constructors taking a std::initializer_list perform a size check at runtime instead of compile time which is quite error-prone at compile time. Ideally, the check needs to be performed at compile-time instead, which is trivially achievable in C++14 as std::initializer_list<T>::size is made constexpr.

Comments (4)

  1. Klaus Iglberger

    Hi Matthias!

    Thanks a lot for pointing out this potential improvement. We indeed missed this detail. We’ll implement the necessary changes for both StaticVector and StaticMatrix. Thanks again,

    Best regards,

    Klaus!

  2. Klaus Iglberger

    Hi Matthias!

    Although the idea is great, it unfortunately doesn't work. In a function taking a std::initializer_list you cannot evaluate the size() member function as constexpr. The best explanation I found is from Dietmar Kühl in this stackoverflow article.

    Thanks again for the creating this issue,

    Best regards,

    Klaus!

  3. Matthias Moulin reporter

    Thanks for the information explaining the underlying motivation of this odd C++ behavior.

    An alternative that would not break backward compatibility for StaticVector (but will break backward compatibility for StaticMatrix), consists of using a variadic templated constructor of which the variable number of arguments can be trivially queried at run-time. The latter should be constraint to at least 2 arguments as the 0 and 1 argument cases are already covered, and should be guarded against potential clashes with the count/pointer constructor.

    This would still allow the following code:

    StaticVector< unsigned long long, 3u > v = { 1u, 2u, 3u };
    

    but not:

    StaticMatrix< int, 2u, 2u > m = { { 0, 1 }, { 2, 3 } };
    

    Instead, some alternatives are possible:

    StaticMatrix< int, 2u, 2u > m = { 0, 1, 2, 3 }; // Alternative 1
    StaticMatrix< int, 2u, 2u > m = { StaticVector< int, 2u >{ 0, 1 }, StaticVector< int, 2u >{ 2, 3 } }; // Alternative 2
    StaticMatrix< int, 2u, 2u > m = {{ {{ 0, 1 }}, {{ 2, 3 }} }}; // Alternative 2
    

    (which are, unfortunately, not very appealing).

  4. Klaus Iglberger

    Hi Matthias!

    This is the technique we use for the AlignedArray class template. However, as you state yourself, this unfortunately does not work for multi-dimensional data structures and the alternatives are definitely not appealing. Since a breaking change at this point is not possible, we unfortunately have to drop this idea.

    Best regards,

    Klaus!

  5. Log in to comment