Note that there are some explanatory texts on larger screens.

plurals
  1. POCan you throw within a conditional expression? (was: How can bounds-checking be extended to multiple dimensions?)
    primarykey
    data
    text
    <p><strong>Note:</strong> I solved the original problem by realizing a completely different one. See the addendum for the new actual problem, but you can read the previous part for context.</p> <p>This is an extension of one of my <a href="https://stackoverflow.com/q/10171525/1010226" title="How can one make a variadic-based chained-indexing function?">previous posts</a>. I made a container class based on that answer:</p> <pre><code>template &lt; typename T, unsigned N0, unsigned ...N &gt; struct array_md { // There's a class template specialization with no extents. // Imagine the various N... components are bracket-enclosed instead // of comma-separated. And if "N..." is empty, then we just have "T" // as the "direct_element_type". (I actually use recursive class // definitions.) using direct_element_type = T[N...]; using data_type = direct_element_type[ N0 ]; template &lt; typename ...Indices &gt; auto operator ()( Indices &amp;&amp;...i ) noexcept( !indexing_result&lt;data_type &amp;, Indices...&gt;::can_throw ) -&gt; typename indexing_result&lt;data_type &amp;, Indices...&gt;::type { return slice(data, static_cast&lt;Indices &amp;&amp;&gt;( i )...); } template &lt; typename ...Indices &gt; constexpr auto operator ()( Indices &amp;&amp;...i ) const noexcept( !indexing_result&lt;data_type &amp;, Indices...&gt;::can_throw ) -&gt; typename indexing_result&lt;data_type &amp;, Indices...&gt;::type { return slice(data, static_cast&lt;Indices &amp;&amp;&gt;( i )...); } data_type data; }; </code></pre> <p>I'm trying to make a version of <code>at</code> for this container. I figured I'll just make a version of <code>slice</code> that takes an exception object. Unlike the general <code>slice</code>, my <code>checked_slice</code> has to take in a built-in array object, since pointers and class types (with <code>operator []</code>) don't have a (standard) way to give me bounds.</p> <pre><code>template &lt; typename E, typename T &gt; inline constexpr auto checked_slice( E &amp;&amp;, T &amp;&amp;t ) noexcept -&gt; T &amp;&amp; { return static_cast&lt;T &amp;&amp;&gt;(t); } template &lt; typename E, typename T, std::size_t N, typename ...V &gt; inline constexpr auto checked_slice( E &amp;&amp;e, T (&amp;t)[N], std::size_t u, V &amp;&amp;...v ) -&gt; typename remove_some_extents&lt;T[N], 1u + sizeof...(V)&gt;::type &amp; { return u &lt; N ? checked_slice( static_cast&lt;E &amp;&amp;&gt;(e), static_cast&lt;T &amp;&gt;(t[ u ]), static_cast&lt;V &amp;&amp;&gt;(v)... ) : throw static_cast&lt;E &amp;&amp;&gt;( e ); } template &lt; typename E, typename T, std::size_t N, typename ...V &gt; inline constexpr auto checked_slice( E &amp;&amp;e, T (&amp;&amp;t)[N], std::size_t u, V &amp;&amp;...v ) -&gt; typename remove_some_extents&lt;T[N], 1u + sizeof...(V)&gt;::type &amp;&amp; { return u &lt; N ? checked_slice( static_cast&lt;E &amp;&amp;&gt;(e),static_cast&lt;T &amp;&amp;&gt;(t[ u ]), static_cast&lt;V &amp;&amp;&gt;(v)... ) : throw static_cast&lt;E &amp;&amp;&gt;( e ); } </code></pre> <p>(The <code>remove_some_extents</code> does what it says, instead of just one or all the C++11 standard library gives you.) When I put this into my <code>at</code>:</p> <pre><code>template &lt; typename T, unsigned N0, unsigned ...N &gt; struct array_md { //... template &lt; typename ...Indices &gt; auto at( Indices &amp;&amp;...i ) -&gt; typename remove_some_extents&lt;data_type, sizeof...( Indices )&gt;::type &amp; { return checked_slice(std::out_of_range{ "Index out of bounds" }, data, static_cast&lt;Indices &amp;&amp;&gt;( i )...); } template &lt; typename ...Indices &gt; constexpr auto at( Indices &amp;&amp;...i ) const -&gt; typename remove_some_extents&lt;data_type,sizeof...( Indices )&gt;::type const &amp; { return checked_slice(std::out_of_range{ "Index out of bounds" }, data, static_cast&lt;Indices &amp;&amp;&gt;( i )...); } //... }; </code></pre> <p>I get errors related to array-to-pointer decay! (I'm using TDC-GCC 4.7.1 that's bundled with CodeBlocks 12.11 for Windows-8 Pro 32-bit.)</p> <pre><code>In file included from container/array_md.hpp:36:0, from test\arraymd_test.cpp:15: utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const int; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const int; std::size_t = unsigned int]': container/array_md.hpp:284:112: required from 'constexpr const typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type&amp; container::array_md&lt;T, M, N ...&gt;::at(Indices&amp;&amp; ...) const [with Indices = {int}; T = int; unsigned int M = 2u; unsigned int ...N = {}; typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type = int]' test\arraymd_test.cpp:224:1: required from here utility/slice.hpp:141:10: warning: returning reference to temporary [enabled by default] utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [2][6]; std::size_t = unsigned int]': container/array_md.hpp:284:112: required from 'constexpr const typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type&amp; container::array_md&lt;T, M, N ...&gt;::at(Indices&amp;&amp; ...) const [with Indices = {int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type = char [2][6]]' test\arraymd_test.cpp:238:1: required from here utility/slice.hpp:141:10: error: invalid initialization of reference of type 'const char (&amp;)[2][6]' from expression of type 'const char (*)[6]' utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [2][6]; std::size_t = unsigned int]' not a return-statement utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [6]; std::size_t = unsigned int]': utility/slice.hpp:141:10: required from 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [6]; std::size_t = unsigned int]' container/array_md.hpp:284:112: required from 'constexpr const typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type&amp; container::array_md&lt;T, M, N ...&gt;::at(Indices&amp;&amp; ...) const [with Indices = {int, int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type = char [6]]' test\arraymd_test.cpp:239:1: required from here utility/slice.hpp:141:10: error: invalid initialization of reference of type 'const char (&amp;)[6]' from expression of type 'const char*' utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [6]; std::size_t = unsigned int]' not a return-statement utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [6]; std::size_t = unsigned int]': container/array_md.hpp:284:112: required from 'constexpr const typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type&amp; container::array_md&lt;T, M, N ...&gt;::at(Indices&amp;&amp; ...) const [with Indices = {int, int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type = char [6]]' test\arraymd_test.cpp:239:1: required from here utility/slice.hpp:141:10: error: invalid initialization of reference of type 'const char (&amp;)[6]' from expression of type 'const char*' utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [6]; std::size_t = unsigned int]' not a return-statement utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {unsigned int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [6]; std::size_t = unsigned int]': container/array_md.hpp:284:112: required from 'constexpr const typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type&amp; container::array_md&lt;T, M, N ...&gt;::at(Indices&amp;&amp; ...) const [with Indices = {int, unsigned int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type = char [6]]' test\arraymd_test.cpp:261:5: required from here utility/slice.hpp:141:10: error: invalid initialization of reference of type 'const char (&amp;)[6]' from expression of type 'const char*' utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {unsigned int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [6]; std::size_t = unsigned int]' not a return-statement utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = int; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = int; std::size_t = unsigned int]': container/array_md.hpp:274:112: required from 'typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type&amp; container::array_md&lt;T, M, N ...&gt;::at(Indices&amp;&amp; ...) [with Indices = {int}; T = int; unsigned int M = 2u; unsigned int ...N = {}; typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type = int]' test\arraymd_test.cpp:220:1: required from here utility/slice.hpp:141:10: error: invalid initialization of non-const reference of type 'remove_some_extents&lt;int [2], 1u&gt;::type&amp; {aka int&amp;}' from an rvalue of type 'int' utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = int; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = int; std::size_t = unsigned int]' not a return-statement utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [2][6]; std::size_t = unsigned int]': container/array_md.hpp:274:112: required from 'typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type&amp; container::array_md&lt;T, M, N ...&gt;::at(Indices&amp;&amp; ...) [with Indices = {int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type = char [2][6]]' test\arraymd_test.cpp:234:1: required from here utility/slice.hpp:141:10: error: invalid initialization of non-const reference of type 'char (&amp;)[2][6]' from an rvalue of type 'char (*)[6]' utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [2][6]; std::size_t = unsigned int]' not a return-statement utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [6]; std::size_t = unsigned int]': utility/slice.hpp:141:10: required from 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [6]; std::size_t = unsigned int]' container/array_md.hpp:274:112: required from 'typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type&amp; container::array_md&lt;T, M, N ...&gt;::at(Indices&amp;&amp; ...) [with Indices = {int, int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type = char [6]]' test\arraymd_test.cpp:235:1: required from here utility/slice.hpp:141:10: error: invalid initialization of non-const reference of type 'char (&amp;)[6]' from an rvalue of type 'char*' utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [6]; std::size_t = unsigned int]' not a return-statement utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [6]; std::size_t = unsigned int]': container/array_md.hpp:274:112: required from 'typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type&amp; container::array_md&lt;T, M, N ...&gt;::at(Indices&amp;&amp; ...) [with Indices = {int, int}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type = char [6]]' test\arraymd_test.cpp:235:1: required from here utility/slice.hpp:141:10: error: invalid initialization of non-const reference of type 'char (&amp;)[6]' from an rvalue of type 'char*' utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [6]; std::size_t = unsigned int]' not a return-statement utility/slice.hpp: In instantiation of 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {long double}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [6]; std::size_t = unsigned int]': container/array_md.hpp:274:112: required from 'typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type&amp; container::array_md&lt;T, M, N ...&gt;::at(Indices&amp;&amp; ...) [with Indices = {int, long double}; T = char [6]; unsigned int M = 2u; unsigned int ...N = {2u}; typename remove_some_extents&lt;typename container::array_md&lt;T, N ...&gt;::data_type [M], sizeof (Indices ...)&gt;::type = char [6]]' test\arraymd_test.cpp:260:5: required from here utility/slice.hpp:141:10: error: invalid initialization of non-const reference of type 'char (&amp;)[6]' from an rvalue of type 'char*' utility/slice.hpp:142:1: error: body of constexpr function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {long double}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [6]; std::size_t = unsigned int]' not a return-statement utility/slice.hpp: In function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {unsigned int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [6]; std::size_t = unsigned int]': utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type] utility/slice.hpp: In function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [6]; std::size_t = unsigned int]': utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type] utility/slice.hpp: In function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [6]; std::size_t = unsigned int]': utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type] utility/slice.hpp: In function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = const char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = const char [2][6]; std::size_t = unsigned int]': utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type] utility/slice.hpp: In function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {long double}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [6]; std::size_t = unsigned int]': utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type] utility/slice.hpp: In function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {int}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [6]; std::size_t = unsigned int]': utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type] utility/slice.hpp: In function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [6]; std::size_t = unsigned int]': utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type] utility/slice.hpp: In function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = char [2][6]; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = char [2][6]; std::size_t = unsigned int]': utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type] utility/slice.hpp: In function 'constexpr typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type&amp; checked_slice(E&amp;&amp;, T (&amp;)[N], std::size_t, V&amp;&amp; ...) [with E = std::out_of_range; T = int; unsigned int N = 2u; V = {}; typename remove_some_extents&lt;T [N], (1u + sizeof (V ...))&gt;::type = int; std::size_t = unsigned int]': utility/slice.hpp:142:1: warning: control reaches end of non-void function [-Wreturn-type] </code></pre> <p>I thought using array references cancels array-to-pointer decay. Is this a GCC bug, or am I messing up somewhere?</p> <p>For "slice.hpp", Line 141, Col. 10 is the end of the statement in the (l-value version of) <code>checked_slice</code> function, while L142C1 is the function's ending bracket. In "array_md.hpp", L284C112 and L274C112 are return (and sole) statements of the <code>at</code> functions, <code>const</code> and non-const respectively. The column is at the "i" inside the <code>static_cast</code>.</p> <p>By the way, here's <code>remove_some_extents</code>:</p> <pre><code>// Forward declaration template &lt; typename Array, std::size_t Count &gt; struct remove_some_extents; // Case with indefinite array but no extents to strip template &lt; typename T &gt; struct remove_some_extents&lt; T[], 0u &gt; { typedef T type[]; }; // Case with definite array but no extents to strip template &lt; typename T, std::size_t N &gt; struct remove_some_extents&lt; T[N], 0u &gt; { typedef T type[N]; }; // Case with non-array type but no extents to strip template &lt; typename T &gt; struct remove_some_extents&lt; T, 0u &gt; { typedef T type; }; // Case with indefinite array and extents to strip template &lt; typename T, std::size_t L &gt; struct remove_some_extents&lt; T[], L &gt; { typedef typename remove_some_extents&lt;T, L - 1u&gt;::type type; }; // Case with definite array and extents to strip template &lt; typename T, std::size_t N, std::size_t L &gt; struct remove_some_extents&lt; T[N], L &gt; { typedef typename remove_some_extents&lt;T, L - 1u&gt;::type type; }; // Right now, non-array type with non-zero strip count should give an error. </code></pre> <p>Thanks.</p> <p><strong>Edit:</strong> Added the base-case and r-value overloads for <code>checked_slice</code>.</p> <p><strong>Addendum:</strong> I got something that works, but I don't know why the old way didn't work.</p> <p>I first commented out the r-value overload for <code>checked_slice</code>, to reduce the variables I have to work with. I then made a version of <code>checked_slice</code> that works for standard containers, but you don't need to see it because it didn't help. (And I commented it out to make sure it didn't make a difference.)</p> <p>I changed the regular version to:</p> <pre><code>template &lt; typename E, typename T, std::size_t N, typename ...V &gt; inline constexpr auto checked_slice( E &amp;&amp;e, T (&amp;t)[N], std::size_t u, V &amp;&amp;...v ) -&gt; typename remove_some_extents&lt;T[N], 1u + sizeof...(V)&gt;::type &amp; { return checked_slice( static_cast&lt;E &amp;&amp;&gt;(e), static_cast&lt;T &amp;&gt;(t[ u ]), static_cast&lt;V &amp;&amp;&gt;(v)... ); } </code></pre> <p>i.e. I removed the actual test and the throw-on-fail parts, and the code worked! The problem didn't seem to be the indexing, but the throw and/or conditional! Sure enough, when I changed it to:</p> <pre><code>template &lt; typename E, typename T, std::size_t N, typename ...V &gt; inline auto checked_slice( E &amp;&amp;e, T (&amp;t)[N], std::size_t u, V &amp;&amp;...v ) -&gt; typename remove_some_extents&lt;T[N], 1u + sizeof...(V)&gt;::type &amp; { if ( u &lt; N ) return checked_slice(static_cast&lt;E &amp;&amp;&gt;(e),t[u],static_cast&lt;V &amp;&amp;&gt;(v)...); else throw e; } </code></pre> <p>It still works! What gives, I thought it was OK to use a throw statement as one of the action parts of a conditional expression? Is it a bug in my compiler?</p> <p>I may have to give up and separate the bounds-check to a pure-function and throw-on-fail within the <code>at</code> method.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload