Earlier quoted context omitted.
I don't see how concepts can emulate signatures to the full extent that the target object can be manipulated as if it conformed to an abstract base, without any wrapper object being required to handle it. Without signatures, we have to use some kind of delegating shim which takes the virtual function calls, and calls the real object. It could be a smart pointer. With signatures, we don't use smart pointers, just "poi…
Here is an example then, assuming you mean this kind of abstrations, #include using namespace std; template concept Speaker = requires (T t) { t.speak(); }; class Duck { public: void speak() const { cout void speaking_animal(const T& animal) { animal.speak(); cout void speaking_farm(const T&... animals) { auto space_adder = [&](auto creature) -> void { creature.speak(); cout Live example, https://godbolt.org/z/vPhf13…
Moreover, everything here can be done without a concept.
This version of the code builds with g++ -std=c++17. We just get worse diagnostics if we try to use something as a Speaker which doesn't conform.
#include
using namespace std;
class Duck {
public:
void speak() const {
cout
void speaking_animal(const T& animal) {
animal.speak();
cout
void speaking_farm(const T&... animals) {
auto space_adder = [&](auto creature) -> void {
creature.speak();
cout
I was thinking about more something along these lines. But note the double indirection: we end up passing the smart pointer animal_pointer by reference.We achieve the "signature thing" though in that we take these animal objects and effectively get them to to conform to the common animal_pointer abstract base without their cooperation.
#include
using namespace std;
class Duck {
public:
void speak() const { cout class animal_pointer_impl : public animal_pointer {
private:
T *obj;
public:
animal_pointer_impl(T *o) : obj(o) { }
virtual void speak() const { obj->speak(); }
};
void animal_api(const animal_pointer &p)
{
p.speak();
cout p0(&duck);
animal_pointer_impl p1(&dog);
animal_pointer_impl p2(&cat);
animal_api(p0);
animal_api(p1);
animal_api(p2);
}
animal_api is a regular function, which represents some external API that we don't get to recompile.