LINUX.ORG.RU

boost::multi_index_container<const int>


0

1

Кто знает почему субж не умеет работать с константными типами?

#include <iostream>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/global_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>

int main()
{
	boost::multi_index_container<const int> t;

	t.insert(5);
	std::cout << *t.begin() << std::endl;
}
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
In file included from /usr/include/x86_64-linux-gnu/c++/4.7/./bits/c++allocator.h:34:0,
                 from /usr/include/c++/4.7/bits/allocator.h:48,
                 from /usr/include/c++/4.7/string:43,
                 from /usr/include/c++/4.7/bits/locale_classes.h:42,
                 from /usr/include/c++/4.7/bits/ios_base.h:43,
                 from /usr/include/c++/4.7/ios:43,
                 from /usr/include/c++/4.7/ostream:40,
                 from /usr/include/c++/4.7/iostream:40,
                 from ../main.cpp:13:
/usr/include/c++/4.7/ext/new_allocator.h: In instantiation of «class __gnu_cxx::new_allocator<const int>»:
/usr/include/c++/4.7/bits/allocator.h:89:11:   required from «class std::allocator<const int>»
/usr/include/boost/detail/allocator_utilities.hpp:149:31:   required from «struct boost::detail::allocator::rebinder<std::allocator<const int> >::result<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<const int, std::allocator<const int> > > >»
/usr/include/boost/detail/allocator_utilities.hpp:158:49:   required from «struct boost::detail::allocator::compliant_allocator_rebind_to<std::allocator<const int>, boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<const int, std::allocator<const int> > > >»
/usr/include/boost/mpl/eval_if.hpp:60:31:   required from «struct boost::mpl::eval_if_c<false, boost::detail::allocator::partial_std_allocator_rebind_to<std::allocator<const int>, boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<const int, std::allocator<const int> > > >, boost::detail::allocator::compliant_allocator_rebind_to<std::allocator<const int>, boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<const int, std::allocator<const int> > > > >»
/usr/include/boost/detail/allocator_utilities.hpp:164:8:   required from «struct boost::detail::allocator::rebind_to<std::allocator<const int>, boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<const int, std::allocator<const int> > > >»
/usr/include/boost/multi_index_container.hpp:70:7:   required from «class boost::multi_index::multi_index_container<const int>»
../main.cpp:22:42:   required from here
/usr/include/c++/4.7/ext/new_allocator.h:83:7: ошибка: «const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = const int; __gnu_cxx::new_allocator<_Tp>::const_pointer = const int*; __gnu_cxx::new_allocator<_Tp>::const_reference = const int&]» cannot be overloaded
/usr/include/c++/4.7/ext/new_allocator.h:79:7: ошибка: with «_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = const int; __gnu_cxx::new_allocator<_Tp>::pointer = const int*; __gnu_cxx::new_allocator<_Tp>::reference = const int&]»
In file included from /usr/include/boost/multi_index/detail/base_type.hpp:21:0,
                 from /usr/include/boost/multi_index_container.hpp:33,
                 from ../main.cpp:15:
/usr/include/boost/multi_index/detail/index_base.hpp: In instantiation of «boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::node_type* boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::insert_(boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type, boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::node_type*) [with Value = const int; IndexSpecifierList = boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<const int>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>; Allocator = std::allocator<const int>; boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::node_type = boost::multi_index::detail::index_node_base<const int, std::allocator<const int> >; boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type = const int]»:
/usr/include/boost/multi_index/ordered_index.hpp:633:63:   required from «boost::multi_index::detail::ordered_index<KeyFromValue, Compare, SuperMeta, TagList, Category>::node_type* boost::multi_index::detail::ordered_index<KeyFromValue, Compare, SuperMeta, TagList, Category>::insert_(boost::multi_index::detail::ordered_index<KeyFromValue, Compare, SuperMeta, TagList, Category>::value_param_type, boost::multi_index::detail::ordered_index<KeyFromValue, Compare, SuperMeta, TagList, Category>::node_type*) [with KeyFromValue = boost::multi_index::identity<const int>; Compare = std::less<const int>; SuperMeta = boost::multi_index::detail::nth_layer<1, const int, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<const int>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<const int> >; TagList = boost::mpl::vector0<mpl_::na>; Category = boost::multi_index::detail::ordered_unique_tag; boost::multi_index::detail::ordered_index<KeyFromValue, Compare, SuperMeta, TagList, Category>::node_type = boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<const int, std::allocator<const int> > >; typename SuperMeta::type::node_type = boost::multi_index::detail::index_node_base<const int, std::allocator<const int> >; boost::multi_index::detail::ordered_index<KeyFromValue, Compare, SuperMeta, TagList, Category>::value_param_type = const int]»
/usr/include/boost/multi_index_container.hpp:488:40:   required from «std::pair<typename boost::multi_index::detail::multi_index_base_type<Value, IndexSpecifierList, Allocator>::type::node_type*, bool> boost::multi_index::multi_index_container<Value, IndexSpecifierList, Allocator>::insert_(const Value&) [with Value = const int; IndexSpecifierList = boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<const int>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>; Allocator = std::allocator<const int>; typename boost::multi_index::detail::multi_index_base_type<Value, IndexSpecifierList, Allocator>::type::node_type = boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<const int, std::allocator<const int> > >]»
/usr/include/boost/multi_index/detail/index_base.hpp:150:30:   required from «std::pair<typename boost::multi_index::detail::multi_index_node_type<Value, IndexSpecifierList, Allocator>::type*, bool> boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::final_insert_(boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type) [with Value = const int; IndexSpecifierList = boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<const int>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>; Allocator = std::allocator<const int>; typename boost::multi_index::detail::multi_index_node_type<Value, IndexSpecifierList, Allocator>::type = boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<const int, std::allocator<const int> > >; boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type = const int]»
/usr/include/boost/multi_index/ordered_index.hpp:275:61:   required from «std::pair<boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<typename SuperMeta::type::node_type> >, bool> boost::multi_index::detail::ordered_index<KeyFromValue, Compare, SuperMeta, TagList, Category>::insert(boost::multi_index::detail::ordered_index<KeyFromValue, Compare, SuperMeta, TagList, Category>::value_param_type) [with KeyFromValue = boost::multi_index::identity<const int>; Compare = std::less<const int>; SuperMeta = boost::multi_index::detail::nth_layer<1, const int, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<const int>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<const int> >; TagList = boost::mpl::vector0<mpl_::na>; Category = boost::multi_index::detail::ordered_unique_tag; typename SuperMeta::type::node_type = boost::multi_index::detail::index_node_base<const int, std::allocator<const int> >; boost::multi_index::detail::ordered_index<KeyFromValue, Compare, SuperMeta, TagList, Category>::value_param_type = const int]»
../main.cpp:24:12:   required from here
/usr/include/boost/multi_index/detail/index_base.hpp:88:5: ошибка: нет соответствующей функции для вызова «construct(boost::multi_index::detail::index_node_base<const int, std::allocator<const int> >::value_type*, boost::multi_index::detail::index_base<const int, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::identity<const int>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<const int> >::value_param_type&)»
/usr/include/boost/multi_index/detail/index_base.hpp:88:5: замечание: candidate is:
In file included from /usr/include/boost/multi_index_container.hpp:20:0,
                 from ../main.cpp:15:
/usr/include/boost/detail/allocator_utilities.hpp:176:6: замечание: template<class Type> void boost::detail::allocator::construct(void*, const Type&)
/usr/include/boost/detail/allocator_utilities.hpp:176:6: замечание:   template argument deduction/substitution failed:
In file included from /usr/include/boost/multi_index/detail/base_type.hpp:21:0,
                 from /usr/include/boost/multi_index_container.hpp:33,
                 from ../main.cpp:15:
/usr/include/boost/multi_index/detail/index_base.hpp:88:5: замечание:   cannot convert «& x->boost::multi_index::detail::index_node_base<Value, Allocator>::value<const int, std::allocator<const int> >()» (type «boost::multi_index::detail::index_node_base<const int, std::allocator<const int> >::value_type* {aka const int*}») to type «void*»
make: *** [main.o] Ошибка 1

Такое чувство, что я единственнй кто это пробовал, ибо в гугле ничего похожего ненашел.


Шаблоны — это хорошо, и можно в них разное пихать... Но тут ты явно бензиновый двигатель решил заправить дровами. Просто попробуй реализовать простенький контейнерный класс, который оперирует const int-ами. Либо поймешь, почему так делать нельзя, либо таки найдешь способ сделать что хотел.

uuwaan ★★ ()

http://www.cplusplus.com/reference/stl тоже не умеют.

Такое чувство, что я единственнй кто это пробовал, ибо в гугле ничего похожего ненашел.

http://stackoverflow.com/q/2759350 и вообще google://any-standard-container+const.

Вот минимальный пример с которым T / const T работает:

template <typename T> // requires: T is regular (http://www.stepanovpapers.com/DeSt98.pdf) type.
struct singleton {
    typedef T value_type;
    T value;
    ~singleton() {}
    singleton() : value() {}
    singleton(singleton const& x) : value(x.value) {}
    explicit singleton(T const& value_) : value(value_) {}
    template <typename U> explicit singleton(singleton<U> const& x) : value(x.value) {}
    operator T() const { return value; }
    singleton& operator=(T const& value_) { value = value_; return *this; }
    singleton& operator=(singleton const& x) { value = x.value; return *this; }
    friend bool operator==(singleton const& x, singleton const& y) { return x.value == y.value; }
    friend bool operator!=(singleton const& x, singleton const& y) { return !(x == y); }
    friend bool operator<(singleton const& x, singleton const& y) { return x.value < y.value; }
    friend bool operator<=(singleton const& x, singleton const& y) { return !(y < x); }
    friend bool operator>(singleton const& x, singleton const& y) { return y < x; }
    friend bool operator>=(singleton const& x, singleton const& y) { return !(x < y); }
};

А если контейнер так не умеет — можно брать C<T> const вместо C<T const> — составить C<T> и передавать как C<T> const& по надобности.

quasimoto ★★★★ ()
Последнее исправление: quasimoto (всего исправлений: 2)
Ответ на: комментарий от quasimoto

requires: T is regular

Хотя в случае singleton<const T> ни const T, ни singleton<const T> уже не regular, так как не assignable. Можно считать это disjoint концептом — Constructible | Copyable | Assignable | Comparable | Ordered (http://www.stroustrup.com/sle2011-concepts.pdf — 5 Concepts for the STL). Вот стандартные контейнеры и multi_index_container устроены так, что хотят Assignable.

quasimoto ★★★★ ()
Ответ на: комментарий от Cupper

Исторически (C++03) — было надо. Сейчас — должно работать, например std::vector<singleton<const int>> работает, хотя singleton<const int> не assignable. Но голый const int чем-то не допилен — у g++ стандартные контейнеры на той же фигне спотыкаются, то есть std::allocator<const int> (__gnu_cxx::new_allocator<const int> и __gnu_cxx::new_allocator<_Tp>::deallocate).

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

Вот так работает:

#include <tuple>
#include <iostream>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>

template <typename T>
using Value = std::tuple<T>;

template <typename T>
T& operator*(Value<T> const& x) { return std::get<0>(x); }

// ...

template <typename T>
using Const = Value<const T>;

int main() {
    boost::multi_index_container<Const<int>> t;
    t.insert(Const<int>(5));
    std::cout << **t.begin() << std::endl;
}

runtime оверхеда быть не должно.

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

И с неявными преобразованиями:

template <typename T>
struct Const {
    const T value;
    Const(T const& value_) : value(value_) {}
    operator const T() const { return value; }
    // ...
};

Тогда в использовании не отличается, только const T на Const<T> заменить:

int main() {
    boost::multi_index_container<Const<int>> t;
    t.insert(5);
    std::cout << *t.begin() << std::endl;
}

Возможно, что с другими компиляторами / на других версиях g++ обычный cosnt тоже будет работать.

quasimoto ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.