> From: John Harris (TT) [mailto:john.harris@tradingtechnologies.com]
>
> Is the author/maintainer of boost::any out there? Is this problem not
> worthy of anyone's reply? As it is, I have to modify boost
> source to get my
> code to work. We want boost::any ctor to be "explicit"...that's it.
>
Well, I think it is worthy of a reply, so here goes ;-)
> I think the template constructor for boost::any is too
> general. I ran into
> the problem while trying to overload
>
> ostream&operator<<(ostream&, const boost::any&)
>
> If I try to do this, then all types are automatically included in this
> overload (because boost::any can be constructed from any type).
>
> I want to provide support for only a couple of types in my
> overload, and
> because of my architecture, I have to have this overload.
Even without an explicit parameterized constructor for any, there are at least two solutions (or rather workarounds):
0) Change the declaration to ostream& operator<<(ostream&,boost::any&)
The removal of const may be enough, but that, of course, depends on cv-qualification of the instances (if your "real" anys are already const that'd clearly break this hack).
1) Another level of indirection - the following should solve the problem:
struct any_print {
any_print(const boost::any& a) : a_(a) {}
const boost::any& a_;
};
std::ostream& operator<<(std::ostream& o, const any_print& a) {
if (const std::string* p=boost::any_cast<std::string>(&(a.a_))) {
std::cout << *p << '\n';
}
else {
std::cout << "No match!\n";
}
return o;
}
Not very pretty, but it gets the job done.
> Is there any reason not to have boost::any::any() be explicit?
>
I think there are reasons:
0) Ease of use. With an explicit constructor, you couldn't do this:
int main() {
std::vector<boost::any> vec;
vec.push_back(5);
vec.push_back(std::string(", this works!"));
// Note that the following line uses the any_print class defined earlier
std::cout << "Because of implicit conversion" << vec[1] << '\n';
return 0;
}
Weak argument? Perhaps.
1) Compiler deficiencies. I gave it a quick try on three compilers, and these were the results:
* Compiler X didn't care about explicit for templated constructors...
* Compiler Y worked!
* Compiler Z understood the explicit part, but couldn't even pass a correctly constructed const any& to functions afterwards...
Weak argument? Perhaps.
Bjorn Karlsson