Почему boost :: equals требует, чтобы диапазоны были копируемыми? - PullRequest
7 голосов
/ 20 декабря 2011

Не могу понять, почему это не удается:

#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;
}

Вывод:

$ 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)

Я пробовал копаться в коде повышения, но это заставляет меня задуматьсявращение.Это кажется абсурдным;так расточительно и ненужно.Что происходит?

1 Ответ

10 голосов
/ 20 декабря 2011

Boost пытается создать набор диапазонов для контейнеров, которые вы передаете, и в итоге он вызывает range_detail::is_char_ptr(), который является именем набора шаблонов функций, который использует вычет параметра шаблона, чтобы определить, является ли параметр char указатель какой-то или нет (как можно догадаться по названию).

К сожалению, шаблон функции 'catch-all', который возвращает 0 при сопоставлении параметров без указателей на символы, принимает свой параметр по значению.

Я думаю, что это можно исправить, изменив параметр на const&. Смотрите в файле boost/range/as_literal.hpp для:

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

и измените его на:

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

Я ни в коем случае не эксперт по реализации сложных библиотек шаблонов (я их использую, я их не пишу), поэтому я не утверждаю, что это изменение не вызовет какой-то другой неприятной стороны. эффект.

...