Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does boost::equals require ranges to be copyable?

Can't for the life of me understand why this fails:

#include <vector>

#include "boost/algorithm/string/predicate.hpp"

struct Test
:
    public std::vector<int>
{
    Test() { }
    Test(const Test&) { assert(false); }
};

int main()
{
    Test a;
    Test b;
    boost::algorithm::equals(a, b);

    return 0;
}

Output:

$ g++ boostEqualsCopyDemo.cpp -I /usr/include/boost-1_47
$ a.out
a.out: boostEqualsCopyDemo.cpp:10: Test::Test(const Test&): Assertion `false' failed.
Aborted (core dumped)

I've tried digging through the boost code but it's making my head spin. It seems absurd; so wasteful and unnecessary. What's going on?

like image 384
voltrevo Avatar asked Dec 20 '11 06:12

voltrevo


People also ask

What is boost range?

Boost.Range is a collection of concepts and utilities that are particularly useful for specifying and implementing generic algorithms.

What is range in algorithm?

You can think of a range as two iterators that refer to the beginning and end of a group of elements that you can iterate over. Because all containers support iterators, every container can be thought of as a range. Since all algorithms from Boost.


1 Answers

Boost is trying to manufacture a set of ranges for the containers you pass in, and it ends up calling range_detail::is_char_ptr(), which is the name of a set of function templates that uses template parameter deduction to determine if the parameter is a char pointer of some sort or not (as you might guess by the name).

Unfortunately, the 'catch-all' function template that returns 0 when matching non-char-pointer parameters takes its parameter by value.

I think this can be fixed by changing the parameter to take a const& instead. Look in the file boost/range/as_literal.hpp for:

    template< class T >
    inline long is_char_ptr( T /* r */ )
    {
        return 0L;
    }

and change it to:

    template< class T >
    inline long is_char_ptr( T const& /* r */ )  // <-- add const&
    {
        return 0L;
    }

I'm by no means an expert in the implementation of complex template libraries (I use 'em, I don't write 'em), so I make no claims that this change won't cause some other nasty side-effect.

like image 121
Michael Burr Avatar answered Oct 31 '22 00:10

Michael Burr