Subject: Re: [Boost-bugs] [Boost C++ Libraries] #1396: wrong result_of invocation around transform_view
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2007-11-22 01:36:19
#1396: wrong result_of invocation around transform_view
----------------------------------------------------+-----------------------
Reporter: Shunsuke Sogame <pstade.mb_at_[hidden]> | Owner: djowel
Type: Bugs | Status: new
Milestone: Boost 1.35.0 | Component: fusion
Version: Boost Development Trunk | Severity: Problem
Resolution: | Keywords:
----------------------------------------------------+-----------------------
Comment (by anonymous):
There needs to be a specialization for both Fun(int&) and
Fun(int):
{{{
struct identity
{
template <typename FunCall>
struct result;
template <typename Fun>
struct result<Fun(int&)>
{
typedef int& type;
};
template <typename Fun>
struct result<Fun(int)>
{
typedef int& type;
};
int& operator()(int& i) const
{
return i;
}
};
}}}
or better yet:
{{{
struct identity
{
template <typename FunCall>
struct result;
template <typename Fun, typename T>
struct result<Fun(T)>
{
typedef typename boost::add_reference<T>::type type;
};
template <typename T>
T& operator()(T& i) const
{
return i;
}
};
}}}
This deserves some explanation. Here's why:
Your initial vector is:
{{{
vector<int, int>
}}}
The underlying types are int and int (hint: not int&).
Now, when as_vector tries to compute the resulting vector,
it calls value_of to know the exact type of the elements in
the input sequence. value_of strips the unnecessary reference
that deref may potentially add. It just so happens that what
you return is a reference, but that's irrelevant. The important
thing is that the input sequence is:
{{{
int, int
}}}
then your identity transform is applied calling
{{{
result<Fun(int)>
}}}
hence, the result:
{{{
int&, int&
}}}
Now...
We haven't started yet. We merely computed the desired result for
as_vector. Now the fun begins, the actual conversion starts.
The input sequence is walked by an iterator. Here, we *deref*
the iterator --which returns an int&. Now, it's obvious why
deref returns a reference -- to avoid copies. But then,
transform_iterator::deref is also called with this reference
parameter, which ultimately calls the identity transform:
{{{
result<Fun(int&)>
}}}
Why doesn't STL iterators have this? It does! It's the value_type.
Now if only std::vector<T&> is allowed, then the both the value_type
and the reference_type would be T&.
Aha! now this is starting to sound like a FAQ :-)
--
Ticket URL: <http://svn.boost.org/trac/boost/ticket/1396#comment:1>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:49:57 UTC