Compilation error with free functions begin() and end()

Issue #424 wontfix
Florian Hirschberger created an issue

Hi Klaus,

using the free functions begin() and end() for non-const iterators with views, e.g. with row(), results in a compilation error. The member functions however work fine.

blaze::DynamicMatrix<double> M;
// ...
std::sort(blaze::begin(blaze::row(M, 0)), blaze::end(blaze::row(M, 0))); // compilation error
std::sort(blaze::row(M, 0).begin(), blaze::row(M, 0).end());             // ok

On a side note: The wiki refers, for example, to auto row1 = row<1UL>( A ); as the 1st row instead of the 2nd row of matrix A.

Best regards,

Florian

Comments (1)

  1. Klaus Iglberger

    Hi Florian!

    Thanks for taking the time to report this potential defect. In this case the behavior is as expected and correct. Allow me to explain.

    In the first call to sort() you are using rvalues in the calls to blaze::begin() and blaze::end(). An rvalue will bind to the version that takes a const reference to a row and thus produces an iterator-to-const:

    std::sort( blaze::begin(blaze::row(M, 0)), blaze::end(blaze::row(M, 0)) );
    

    The first solution is to give the row a name and thus make it an lvalue. This will result in the desired kind of iterators:

    auto row0 = blaze::row(M, 0);
    std::sort( blaze::begin(row0), blaze::end(row0));
    

    The second solution is to call the member functions, which do not distinguish between lvalues and rvalues. Thus you will get iterators to mutable elements:

    std::sort( blaze::row(M, 0).begin(), blaze::row(M, 0).end() );
    

    From my own point of view I consider this last "solution" as potentially problematic, but will not change it since all of the STL works in the same way.

    I hope this explains the problem. Thanks again,

    Best regards,

    Klaus!

  2. Log in to comment