
I'm trying to learn to use BOOST_CONCEPT_CHECK for custom iterators,
ranges, and containers. I've built a simple linked list class with an
iterator (and const_iterator) that, as far as I can tell, satisfies the
forward traversal iterator requirements. However, g++ gives the
following errors:
concept.cpp:81: error: `*' cannot appear in a constant-expression
concept.cpp:81: error: a call to a constructor cannot appear in a
constant-expression
concept.cpp:81: error: template argument 1 is invalid
concept.cpp:81: error: template argument 1 is invalid
concept.cpp:82: error: `*' cannot appear in a constant-expression
concept.cpp:82: error: a call to a constructor cannot appear in a
constant-expression
concept.cpp:82: error: template argument 1 is invalid
concept.cpp:82: error: template argument 1 is invalid
concept.cpp:83: error: `*' cannot appear in a constant-expression
concept.cpp:83: error: a call to a constructor cannot appear in a
constant-expression
concept.cpp:83: error: template argument 1 is invalid
concept.cpp:83: error: template argument 1 is invalid
concept.cpp:84: error: `*' cannot appear in a constant-expression
concept.cpp:84: error: a call to a constructor cannot appear in a
constant-expression
concept.cpp:84: error: template argument 1 is invalid
concept.cpp:84: error: template argument 1 is invalid
Compiling with -E, lines 81-84 are as follows:
typedef ::boost::concepts::detail::instantiate<
&::boost::concepts::requirement_ ));
BOOST_CONCEPT_ASSERT((boost::concepts::WritableIterator<iterator>)); BOOST_CONCEPT_ASSERT((boost::concepts::ForwardTraversalIterator

On Thu, May 24, 2012 at 8:39 AM, McNamara, Nate
**
I'm trying to learn to use BOOST_CONCEPT_CHECK for custom iterators, ranges, and containers. I've built a simple linked list class with an iterator (and const_iterator) that, as far as I can tell, satisfies the forward traversal iterator requirements. However, g++ gives the following errors:
concept.cpp:81: error: `*' cannot appear in a constant-expression concept.cpp:81: error: a call to a constructor cannot appear in a constant-expression concept.cpp:81: error: template argument 1 is invalid concept.cpp:81: error: template argument 1 is invalid concept.cpp:82: error: `*' cannot appear in a constant-expression concept.cpp:82: error: a call to a constructor cannot appear in a constant-expression concept.cpp:82: error: template argument 1 is invalid concept.cpp:82: error: template argument 1 is invalid concept.cpp:83: error: `*' cannot appear in a constant-expression concept.cpp:83: error: a call to a constructor cannot appear in a constant-expression concept.cpp:83: error: template argument 1 is invalid concept.cpp:83: error: template argument 1 is invalid concept.cpp:84: error: `*' cannot appear in a constant-expression concept.cpp:84: error: a call to a constructor cannot appear in a constant-expression concept.cpp:84: error: template argument 1 is invalid concept.cpp:84: error: template argument 1 is invalid
Compiling with -E, lines 81-84 are as follows:
typedef ::boost::concepts::detail::instantiate< &::boost::concepts::requirement_
::failed> boost_concept_check81; typedef ::boost::concepts::detail::instantiate< &::boost::concepts::requirement_
::failed> boost_concept_check82; typedef ::boost::concepts::detail::instantiate< &::boost::concepts::requirement_
)>::failed> boost_concept_check83; typedef ::boost::concepts::detail::instantiate< &::boost::concepts::requirement_
)>::failed> boost_concept_check84; That tells me that, regardless of why g++ is having trouble, my iterator fails to satisfy the concept somehow. So I wrote some code (see my_naive_check, below) to try to figure out which requirement is failing, but my check code is missing the same thing as the iterator, because the check code runs fine.
Any pointers much appreciated.
Hmmm...the below code (with a slight modification) compiles for me on MSVC9, Boost 1.49.0.
// concept.cpp
// What's wrong with the iterators?
#include <cassert> #include <cstdlib> #include <iostream> #include <string>
#include
#include #include #include #include template <typename T> class List { struct Node { Node(const T& value_, Node *next_): value(value_), next(next_) {} T value; Node *next; } *head;
public: List(): head(0) {}
~List() { Node *node = head; while (node) { Node *tmp = node->next; delete node; node = tmp; } }
void push_front(const T& value) { head = new Node(value, head); }
class iterator: public boost::iterator_facade
{ public: iterator(): node(0) {} private: iterator(Node * const node_): node(node_) {} friend class List;
friend class boost::iterator_core_access; T& dereference() const { return node->value; } bool equal(const iterator& rhs) const { return node == rhs.node; } void increment() { node = node->next; }
Node *node; };
iterator begin() { return iterator(head); } iterator end() { return iterator(); }
class const_iterator: public boost::iterator_facade
{ public: const_iterator(): node(0) {} const_iterator(const iterator& old): node(old.node) {} private: friend class boost::iterator_core_access; const T& dereference() const { return node->value; } bool equal(const const_iterator& rhs) const { return node == rhs.node; } void increment() { node = node->next; }
const Node *node; };
const_iterator begin() const { return const_iterator(head); } const_iterator end() const { return const_iterator(); }
I don't know where the following concept checking classes are defined, but from [1], it appears you should be using boost_concepts::ForwardTraversalConcept, etc. (badly named, IMHO, but that's what I'm finding in the documentation).
BOOST_CONCEPT_ASSERT((boost::concepts::ForwardTraversalIterator<iterator>)); BOOST_CONCEPT_ASSERT((boost::concepts::WritableIterator<iterator>));
BOOST_CONCEPT_ASSERT((boost::concepts::ForwardTraversalIterator
)); BOOST_CONCEPT_ASSERT((boost::concepts::ReadableIterator
)); }; /* ForwardTraversalIterator must be SinglePassIterator IncrementableIterator Assignable Copy Constructible &r == &++r r++ *r++ == != difference_type DefaultConstructible iterator_traversal<X>::type => forward_traversal_tag */ void my_naive_check(Liststd::string& words) { typedef Liststd::string::iterator It; It it1 = words.end(); it1 = words.begin(); &it1 == &++it1; It it2 = it1++; std::string word = *it2++; assert(it1 == it2); assert(words.begin() != words.end()); It::difference_type distance = 0; It it3; boost::forward_traversal_tag tag = boost::iterator_traversal<It>::type(); }
int main() { Liststd::string words; words.push_front("world"); words.push_front("Hello"); my_naive_check(words); boost::for_each(words, std::cout << boost::lambda::_1 << "\n"); return EXIT_SUCCESS; }
(Also, could you please use plain formatting in your emails? It makes it easier to reply inline and easier to read across a wide variety of media. Thanks.) - Jeff [1] http://www.boost.org/doc/libs/1_49_0/libs/iterator/doc/iterator_concepts.htm...
participants (2)
-
Jeffrey Lee Hellrung, Jr.
-
McNamara, Nate