Boost logo

Boost Users :

From: Agoston Bejo (gusz1_at_[hidden])
Date: 2004-05-31 17:39:19


Hi,
Please take a look at the code below.
The point is that for_each_treenode calls for_each_treenode_child. It seems
to me that
bind(Print, ref(cout), _1)(&t);
is not the same as
Print(cout, &t);
But if this is the case, how come that
for_each_treenode_child(&t, bind(Print, ref(cout), _1));
compiles and works without problem?
The compiler I use is VC 7.1.

Thx,
Gus

----------------------------------------------------------------------

// xBindTemplFuncPtr.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
using namespace std;
using namespace boost;

template<typename TTree, typename TFunc>
void for_each_treenode_child(TTree* t, TFunc f)
{
 for_each(t->children.begin(), t->children.end(),
   f );
}

template<typename TTree, typename TFunc>
void for_each_treenode(TTree *t, TFunc f)
{
 void (*thisFunc)(TTree*, TFunc) = for_each_treenode;
  // COMPILER BUG WORKAROUND - NOT RELEVANT NOW
 for_each_treenode_child(
  t,
  boost::bind(thisFunc, _1, f)
  );
 f(t);
}

struct Tree {
 typedef vector<Tree*> Container;
 typedef Container::const_iterator const_iterator;
 typedef Container::iterator iterator;
 const_iterator begin() const { return children.begin(); }
 const_iterator end() const { return children.end(); }
 iterator begin() { return children.begin(); }
 iterator end() { return children.end(); }
 Tree(const string& sData):data(sData) {}

 vector<Tree*> children;
 string data;
};

void Print(ostream& out, const Tree* pTree) {
 out << pTree->data << " ";
}

void PrintStd(const Tree* pTree) {
 Print(cout, pTree);
}

int _tmain(int argc, _TCHAR* argv[])
{
 Tree t("t"), t1("t1"), t2("t2"), t11("t11"), t12("t12"), t21("t21");
 t.children.push_back(&t1);
 t1.children.push_back(&t11);
 t1.children.push_back(&t12);
 t.children.push_back(&t2);
 t2.children.push_back(&t21);
 Print(cout, &t); // WORKS
 bind(Print, ref(cout), _)(&t); // GENERATES ERROR (1)
 for_each_treenode(&t, bind(Print, ref(cout), _1)); // GENERATES ERROR (2)
 cout << endl;
 for_each_treenode(&t, PrintStd); // WORKS
 cout << endl;
 for_each_treenode_child(&t, bind(Print, ref(cout), _1)); // WORKS
 cout << endl;
 return 0;
}

------------------------------------------------------------------------

Error for (1):

error C2664: 'boost::_bi::bind_t<R,F,L>::result_type
boost::_bi::bind_t<R,F,L>::operator

()<Tree*__w64 >(A1 & ) const' : cannot convert parameter 1 from 'Tree *__w64
' to 'Tree

*__w64 & '
        with
        [
            R=void,
            F=void (__cdecl *)(std::ostream &,const Tree *),

L=boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ostr
eam>,boost::arg<

1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost::
arg<1>>::B2>,
            A1=Tree *__w64
        ]
        A reference that is not to 'const' cannot be bound to a non-lvalue

Error for (2):

c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\boost\bind.hpp(246) : error

C2664: 'void (TTree *,TFunc)' : cannot convert parameter 2 from

'boost::_bi::result_traits<R,F>::type' to 'boost::_bi::bind_t<R,F,L>'
        with
        [
            TTree=Tree,
            TFunc=boost::_bi::bind_t<void,void (__cdecl *)(std::ostream
&,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>
        ]
        and
        [
            R=void,
            F=void (__cdecl *)(std::ostream &,const Tree *)
        ]
        and
        [
            R=void,
            F=void (__cdecl *)(std::ostream &,const Tree *),

L=boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ostr
eam>,boost::arg<

1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost::
arg<1>>::B2>
        ]
        Expressions of type void cannot be converted to other types
        c:\Program Files\Microsoft Visual Studio .NET

2003\Vc7\include\boost\bind\bind_template.hpp(33) : see reference to
function template

instantiation 'R boost::_bi::list2<A1,A2>::operator

()<boost::_bi::bind_t<R,F,L>::result_type,void(__cdecl *)(TTree

*,TFunc),boost::_bi::list1<Tree & >>(boost::_bi::type<T>,void,A &)' being
compiled
        with
        [
            R=boost::_bi::bind_t<void,void (__cdecl *)(std::ostream &,const
Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>::

result_type,

A1=boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<void,void (__cdecl

*)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>>:

:B1,

A2=boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<void,void (__cdecl

*)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>>:

:B2,
            F=void (__cdecl *)(std::ostream &,const Tree *),

L=boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ostr
eam>,boost::arg<

1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost::
arg<1>>::B2>,
            TTree=Tree,
            TFunc=boost::_bi::bind_t<void,void (__cdecl *)(std::ostream
&,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>,
            T=boost::_bi::bind_t<void,void (__cdecl *)(std::ostream &,const
Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,bo
ost::arg<1>>::B2>>::result_type,
            A=boost::_bi::list1<Tree *& >
        ]
        c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\algorithm(21) : see

reference to function template instantiation
'boost::_bi::bind_t<R,F,L>::result_type

boost::_bi::bind_t<R,F,L>::operator ()<std::allocator<_Ty>::value_type>(A1
& )' being

compiled
        with
        [
            R=void,
            F=void (__cdecl *)(Tree *,boost::_bi::bind_t<void,void (__cdecl
*)(std::ostream

&,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>),

L=boost::_bi::list2<boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<v
oid,void

(__cdecl *)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>>:

:B1,boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<void,void
(__cdecl

*)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>>:

:B2>,
            _Ty=Tree *,
            A1=std::allocator<Tree *>::value_type
        ]
        c:\PROG\VCPP\xBindTemplFuncPtr\xBindTemplFuncPtr.cpp(18) : see
reference to function

template instantiation '_Fn1

std::for_each<std::vector<_Ty>::iterator,TFunc>(_InIt,_InIt,_Fn1)' being
compiled
        with
        [
            _Fn1=boost::_bi::bind_t<void,void (__cdecl *)(Tree

*,boost::_bi::bind_t<void,void (__cdecl *)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>),

boost::_bi::list2<boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<voi
d,void (__cdecl

*)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>>:

:B1,boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<void,void
(__cdecl

*)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>>:

:B2>>,
            _Ty=Tree *,
            TFunc=boost::_bi::bind_t<void,void (__cdecl *)(Tree

*,boost::_bi::bind_t<void,void (__cdecl *)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>),

boost::_bi::list2<boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<voi
d,void (__cdecl

*)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>>:

:B1,boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<void,void
(__cdecl

*)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<s
td::ostream>,boost::arg<1>>::B2>>>::B2>>,
            _InIt=std::vector<Tree *>::iterator
        ]
        c:\PROG\VCPP\xBindTemplFuncPtr\xBindTemplFuncPtr.cpp(29) : see
reference to function

template instantiation 'void
for_each_treenode_child<TTree,boost::_bi::bind_t<R,F,L>>(TTree

*,TFunc)' being compiled
        with
        [
            TTree=Tree,
            R=void,
            F=void (__cdecl *)(Tree *,boost::_bi::bind_t<void,void (__cdecl
*)(std::ostream

&,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>),

L=boost::_bi::list2<boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<v
oid,void

(__cdecl *)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>>:

:B1,boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<void,void
(__cdecl

*)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>>:

:B2>,
            TFunc=boost::_bi::bind_t<void,void (__cdecl *)(Tree

*,boost::_bi::bind_t<void,void (__cdecl *)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>),

boost::_bi::list2<boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<voi
d,void (__cdecl

*)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>>:

:B1,boost::_bi::list_av_2<boost::arg<1>,boost::_bi::bind_t<void,void
(__cdecl

*)(std::ostream &,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::refere
nce_wrapper<std::ostream>,boost::arg<1>>::B2>>>::B2>>
        ]
        c:\PROG\VCPP\xBindTemplFuncPtr\xBindTemplFuncPtr.cpp(68) : see
reference to function

template instantiation 'void
for_each_treenode<Tree,boost::_bi::bind_t<R,F,L>>(TTree

*,TFunc)' being compiled
        with
        [
            R=void,
            F=void (__cdecl *)(std::ostream &,const Tree *),

L=boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ostr
eam>,boost::arg<

1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost::
arg<1>>::B2>,
            TTree=Tree,
            TFunc=boost::_bi::bind_t<void,void (__cdecl *)(std::ostream
&,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>
        ]
c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\boost\bind.hpp(246) : error

C2664: 'void (TTree *,TFunc)' : cannot convert parameter 1 from

'boost::_bi::result_traits<R,F>::type' to 'Tree *'
        with
        [
            TTree=Tree,
            TFunc=boost::_bi::bind_t<void,void (__cdecl *)(std::ostream
&,const Tree

*),boost::_bi::list2<boost::_bi::list_av_2<boost::reference_wrapper<std::ost
ream>,boost::arg

<1>>::B1,boost::_bi::list_av_2<boost::reference_wrapper<std::ostream>,boost:
:arg<1>>::B2>>
        ]
        and
        [
            R=void,
            F=void (__cdecl *)(std::ostream &,const Tree *)
        ]
        Expressions of type void cannot be converted to other types


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net