Re: With Concepts, it seems a truly heterogeneous container is almost there, but...
Lourens Veen wrote:
But that would mean a major change to C++. You would have to have type
names and function signatures available at runtime, and have some
sort of runtime call-by-name mechanism. Also all objects would have
to carry type information with them (which may include information on
a large inheritance hierarchy, so that an inherited member function
can be called). In essence, you would have to introduce dynamic
typing to C++. It's probably possible, yes, but I'm not sure whether
it would still be C++.
Unless I've overlooked something, I think you are overstating things a
bit here. Although RTTI is needed to select the function to call, the
type information derived from the concept determines function
signatures at compile time. AFAIKT a mechanism similar to virtual
functions can be used. Using OP's example, the call {textable.text
("...");} could generate the following pseudo code:
const __Textable::vtable* vtbl =
__Textable::lookup_vtable (typeid (textable));
assert (vtbl);
(*vtbl) [__Textable::text_index] (&textable, "...");
On the other hand, if it walks like a duck, talks like a duck, and
should be seen as a duck by everyone stocking it, then the code
should reflect that. The proper way to express this relationship is
to derive "it" from a "duck" abstract class.
Well, that's not a solution if you have no access to the code in
question. The obvious example being libraries. Duck-typing is most
useful for types over which you have no control. The OP's example
doesn't highlight this. Here's another example (using invented syntax
{auto <Concept>} to name a "heterogenous type"):
// --- Their code ---
namespace Vendor1 {
class HtmlElement {
public:
std::string GetContent () const;
};
}
namespace Vendor2 {
struct html_element {...};
const char* get_content (const html_element*);
}
// --- Our code ---
concept HtmlElementLike <typename T> {
std::string content () const;
};
concept_map HtmlElementLike <Vendor1::HtmlElement> {
std::string content () const {
return Vendor1::GetContent ();
}
};
concept_map HtmlElementLike <Vendor2::html_element> {
std::string content () const {
return std::string (Vendor2::get_content (this));
}
};
class ContentCollection {
typedef auto <HtmlElementLike>* ElementPtr;
std::vector <ElementPtr> container;
public:
void AddContent (ElementPtr element) {
container.push_back (element);
}
void OutputContent (std::ostream& os) const {
for (const ElementPtr element: container)
os << element->content ();
}
};
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]