Boost logo

Boost :

Subject: Re: [boost] [type_erasure] Difficulties with const
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2012-09-13 16:42:31


* ping *

> Hi Steven,
>
> I have a const problem. Consider the following classes:
>
> struct Something
> {
> Something(const char* n): myName(n){}
> std::string const& getName()const
> {
> return myName;
> }
> std::string myName;
> };
>
> struct Container
> {
> typedef std::vector< AnyNameable > PublicData;
>
> Container()
> {
> Something s1("bla");
> Something s2("blabla");
> myData.push_back(s1);
> myData.push_back(s2);
> }
>
> PublicData getData()const
> {
> PublicData res;
> for (Data::const_iterator it = myData.begin(); it != myData.end() ;
> ++it)
> {
> res.push_back(AnyNameable(*it));
> }
> return res;
> }
> private:
> typedef std::vector< Something > Data;
> Data myData;
> };
>
> Container is simply a class returning its "Something", hidden behind
> AnyNameable (nice way to realize C++ Coding Standards Item 42 BTW).
>
> I have a simple test function:
> void test()
> {
> Container c;
> Container::PublicData data = c.getData();
> for (Container::PublicData::const_iterator it = data.begin(); it !=
> data.end() ;++it)
> {
> AnyNameable a(*it);
> std::cout << "data: " << a.getName() << std::endl;
> // auxiliary question: why does this not work if I use const _self&?
> //std::cout << "data: " << (*it).getName() << std::endl;
> }
> }
>
> int main()
> {
> test();
> return 0;
> }
>
> Now comes the interesting part. If I define AnyNameable using the
> concept interface, all goes (almost) well:
>
> template<class C, class T>
> struct getName
> {
> static T apply(C const& cont) { return cont.getName(); }
> };
> namespace boost {
> namespace type_erasure {
> template<class C, class T, class Base>
> struct concept_interface< ::getName<C, T>, Base, C> : Base
> {
> T getName()
> { return call(::getName<C, T>(), *this); }
> };
> }
> }
>
> typedef any<
> mpl::vector<
> getName<_self,std::string const&>,
> relaxed_match,
> copy_constructible<>,
> typeid_<>
> >,
> const _self&
> >
> AnyNameable;
>
> This compiles and outputs as expected.
>
> Problem 1: This will not compile
> std::cout << "data: " << (*it).getName() << std::endl;
>
> Hmmm ok not so bad. I'll gladly pay the extra line. (interestingly, it
> would compile and work without const)
>
>
> Problem 2: if I use the MEMBER macro:
>
> BOOST_TYPE_ERASURE_MEMBER((has_getName), getName, 0);
> typedef any<
> mpl::vector<
> has_getName<std::string const&()>,
> relaxed_match,
> copy_constructible<>,
> typeid_<>
> >,
> const _self&
> >
> AnyNameable;
>
> Then the code does not compile, unless I accept to give up all of my
> consts.
> On one hand, I will find it a easier job to sell type_erasure with the
> macro, OTOH, I will not give up my consts ;-)
>
> Would it be possible to have the macro AND const-correctness?
>
> Attached, a small test with the complete code.
>
> Thanks,
> Christophe
>

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

>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk