|
Boost : |
Subject: [boost] [type_erasure] Difficulties with const
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2012-08-30 05:20:41
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk