From: Alberto Ganesh Barbati on
Terry G ha scritto:
>> Because back_inserter_iterator<> is an output iterator but not an input
>> iterator. value_type, which is defined as the type able to hold the
>> value of the expression *it, makes sense only for input iterators.
>
> What if I want to know what type *it will return?
>

The requirement of an output iterator says that the expression "*it = v"
is well-defined and does what it's supposed to do, but it's not said
what the expression "*it" is required to be and even if it can be used
in any way different from "*it = v". Therefore, defining value_type to
be void is a big warning sign that you shouldn't rely on the actual
type. It's like this for your own good. Why do you want to know?

Ganesh

PS: once we have decltype in the language, we could write decltype(*it),
but the question remains: what for?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Clark S. Cox III on
Terry G wrote:
>> Because back_inserter_iterator<> is an output iterator but not an input
>> iterator. value_type, which is defined as the type able to hold the
>> value of the expression *it, makes sense only for input iterators.
>
> What if I want to know what type *it will return?

Who says that *it returns anything useful? (Hint, for output iterators
like back_insert_iterator or insert_iterator, *it is not required to
return anything that can be used in any way other than assigning to it)


--
Clark S. Cox III
clarkcox3(a)gmail.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Terry G on
Ganesh wrote:
> The requirement of an output iterator says that the expression "*it = v"
> is well-defined and does what it's supposed to do, but it's not said
> what the expression "*it" is required to be and even if it can be used
> in any way different from "*it = v". Therefore, defining value_type to
> be void is a big warning sign that you shouldn't rely on the actual
> type. It's like this for your own good. Why do you want to know?

> PS: once we have decltype in the language, we could write decltype(*it),
> but the question remains: what for?

What for? Uh.. well I'm probably trying to do a "bad thing", but...

Say I have a template function

template <class OutIter>
OutIter CopyOut(OutIter iter) {
// What type does user want? I.e. what is OutIter::value_type?
// Some appropriate logic to output internal state to users container.
} // CopyOut

The idea is that I have some internal information that I want to give to my
user.
Previously, I just returned a vector<MyType>, forcing a container, a copy,
and a type.
I wanted to be more flexible, allowing the user to specify any convertible
type, avoid an unnecessary copy,
and let her pick whatever container.

terry



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Alberto Ganesh Barbati on
Terry G ha scritto:
> Ganesh wrote:
>
> Say I have a template function
>
> template <class OutIter>
> OutIter CopyOut(OutIter iter) {
> // What type does user want? I.e. what is OutIter::value_type?
> // Some appropriate logic to output internal state to users container.
> } // CopyOut

Fact is that OutIter::value_type may not (and usually does not) convey
any useful information. Even decltype(*iter) is not going to provide
useful information for "pure" output iterators, such as
std::back_inserter_iterator. If fact, if you look at the definition of
std::back_inserter_iterator, the type of *iter is...
std::back_inserter_iterator itself! For another kind of output iterator
it might have been any proxy class.

> The idea is that I have some internal information that I want to give to my
> user.

Which kind of information are you thinking about? Could you be more precise?

> Previously, I just returned a vector<MyType>, forcing a container, a copy,
> and a type.

Previously? I'm sorry but I can't follow you there. You did not post any
"previous" code to refer to. How could you expect people to understand?

> I wanted to be more flexible, allowing the user to specify any convertible
> type, avoid an unnecessary copy,
> and let her pick whatever container.

Please provide us a *working* code snippet of what you have but you
don't like and some (obviously not working, but hopefully clarifying)
code of what you would like to have. Otherwise we (both you and I) are
just losing our time.

Ganesh

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Howard Hinnant on
In article <4qV8h.51940$uv5.351593(a)twister1.libero.it>,
Alberto Ganesh Barbati <AlbertoBarbati(a)libero.it> wrote:

> Terry G ha scritto:
> >> Because back_inserter_iterator<> is an output iterator but not an input
> >> iterator. value_type, which is defined as the type able to hold the
> >> value of the expression *it, makes sense only for input iterators.
> >
> > What if I want to know what type *it will return?
> >
>
> The requirement of an output iterator says that the expression "*it = v"
> is well-defined and does what it's supposed to do, but it's not said
> what the expression "*it" is required to be and even if it can be used
> in any way different from "*it = v". Therefore, defining value_type to
> be void is a big warning sign that you shouldn't rely on the actual
> type. It's like this for your own good. Why do you want to know?
>
> Ganesh
>
> PS: once we have decltype in the language, we could write decltype(*it),
> but the question remains: what for?

I know why *I* want output iterators to have value_type. Because I want
to write generic code like:

template <class It>
It
format(char val, It first, It last)
{
typedef typename std::iterator_traits<It>::value_type value_type;
if (first == last)
throw format_error();
*first = static_cast<value_type>(val);
return ++first;
}

I.e. I don't want the return type of *it (which should be it::reference
anyway, and it is fine with me if *it returns void). I want a type such
that if I convert my value v to that type, I'm assured of a clean
assignment into the output iterator.

Note that I'm also wanting output iterators to be equality comparable.
In the case of back_insert_iterator, the following definitions would be
fine:

bool operator==(const back_insert_iterator&,
const back_insert_iterator&)
{return false;}

bool operator!=(const back_insert_iterator&,
const back_insert_iterator&)
{return true;}

With such changes I could safely format a char into any "iterator
delimited stream".

template <class Container>
class back_insert_iterator
{
protected:
Container* container;

public:
typedef Container container_type;
typedef output_iterator_tag iterator_category;
typedef typename container_type::value_type value_type;
typedef ptrdiff_t difference_type;
typedef typename container_type::pointer pointer;
typedef back_insert_iterator& reference;

explicit back_insert_iterator(Container& x) : container(&x) {}
back_insert_iterator& operator=(const value_type& value)
{container->push_back(value); return *this;}
back_insert_iterator& operator=(value_type&& value)
{container->push_back(std::move(value)); return *this;}

reference operator*() {return *this;}
reference operator++() {return *this;}
reference operator++(int) {return *this;}

friend bool operator==(const back_insert_iterator&,
const back_insert_iterator&) {return false;}
friend bool operator!=(const back_insert_iterator&,
const back_insert_iterator&) {return true;}
};

-Howard

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6
Prev: The D Programming Language
Next: CRTP question