|
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