What do I have to do to make custom classes (that inherit from STL containers like std::vector
or std::map
) work with the boost::assign
list_of()
or map_list_of()
initializer functions?
I want to easily initialize a containers with a list of values. C++11 introduced initializer lists however I am stuck with C++03 so I cannot use C++11 initializer lists .
As a workaround I found the boost:assign library that provides functions like list_of() and map_list_of(). This works quite well for the STL containers like std::vector and std::map. However if I create my own containers by eg by extending std::vector I get compilation errors.
Here is a small example
#include "boost/assign/list_of.hpp"
using namespace boost::assign;
#include <vector>
struct SpecialVector : public std::vector<int>{
foo(){/* adds functionality */}
};
int main(){
std::vector<int> v = list_of(1)(2)(3); // list_of() works well for STL containers
// The following works but requires adding items one-by-one with push_back
SpecialVector u;
u.push_back(1);
u.push_back(2);
u.push_back(3);
// The following fails when attempting to compile
SpecialVector u2 = list_of(1)(2)(3);
}
Attempting to compile the example gives me the following error:
In file included from assign_inherited.cpp:1:0:
../../../lib/boost/assign/list_of.hpp: In instantiation of 'Container boost::assign_detail::converter<DerivedTAssign, Iterator>::convert(const Container*, boost::assign_detail::default_type_tag) const [with Container = SpecialVector; DerivedTAssign = boost::assign_detail::generic_list<int>; Iterator = std::_Deque_iterator<int, int&, int*>]':
../../../lib/boost/assign/list_of.hpp:142:38: required from 'Container boost::assign_detail::converter<DerivedTAssign, Iterator>::convert_to_container() const [with Container = SpecialVector; DerivedTAssign = boost::assign_detail::generic_list<int>; Iterator = std::_Deque_iterator<int, int&, int*>]'
../../../lib/boost/assign/list_of.hpp:436:81: required from 'boost::assign_detail::generic_list<T>::operator Container() const [with Container = SpecialVector; T = int]'
assign_inherited.cpp:19:39: required from here
../../../lib/boost/assign/list_of.hpp:163:20: error: no matching function for call to 'SpecialVector::SpecialVector(boost::assign_detail::converter<boost::assign_detail::generic_list<int>, std::_Deque_iterator<int, int&, int*> >::iterator, boost::assign_detail::converter<boost::assign_detail::generic_list<int>, std::_Deque_iterator<int, int&, int*> >::iterator)'
return Container( begin(), end() );
^~~~~~~~~~~~~~~~~~~~~~~~~~~
assign_inherited.cpp:5:8: note: candidate: SpecialVector::SpecialVector()
struct SpecialVector : public std::vector<int>{
^~~~~~~~~~~~~
assign_inherited.cpp:5:8: note: candidate expects 0 arguments, 2 provided
assign_inherited.cpp:5:8: note: candidate: SpecialVector::SpecialVector(const SpecialVector&)
assign_inherited.cpp:5:8: note: candidate expects 1 argument, 2 provided
I already checked the documentation of the boost::assign library. I found the section Extending the library , however if I understand it correctly, this section deals with adding custom classes as items in the list , not with generating an initializer for a custom class . Or did I understand this wrong?
Like you said, you need to allow the construction from base types:
#include "boost/assign/list_of.hpp"
using namespace boost::assign;
#include <vector>
struct SpecialVector : std::vector<int>{
typedef std::vector<int> base;
void foo(){/* adds functionality */}
SpecialVector() : base() {}
template <typename T> explicit SpecialVector(T const& t) : base(t) {}
template <typename T, typename U> SpecialVector(T const& t, U const& u) : base(t, u) {}
template <typename T, typename U, typename V> SpecialVector(T const& t, U const& u, V const& v) : base(t, u, v) {}
};
int main(){
std::vector<int> v = list_of(1)(2)(3); // list_of() works well for STL containers
// The following works but requires adding items one-by-one with push_back
SpecialVector u;
u.push_back(1);
u.push_back(2);
u.push_back(3);
// The following fails when attempting to compile
SpecialVector u2 = list_of(1)(2)(3);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.