Is it possible to mimic polymorphism using concepts with c++20?

Viewed 141

The question is pretty much given in the titel. Please considere the following godbolted code:

#include <iostream>

struct Base{};
struct Derived : Base{};

template<typename T>
concept IsDerivedFromBase = std::same_as<T, Base>;

template<typename T>
concept IsNotDerivedFromBase = not IsDerivedFromBase<T>;

template <IsDerivedFromBase T>
void foo(T bar) {std::cout << "IsBase" << std::endl;}

template <IsNotDerivedFromBase T>
void foo(T bar) {std::cout << "IsNotBase" << std::endl;}

int main()
{
    Base a;
    foo(a);

    Derived b;
    foo(b);

    Base* c = new Derived{};
    foo(*c);
    delete c;
}

The output of the above code reads:

IsBase
IsNotBase
IsBase

I am asking if it is possible to modify the concepts somehow in order to mimic polymorphism. The output should read:

IsBase
IsNotBase
IsNotBase
1 Answers

Everything concept-related is determined and "worked out" at compile time. Setting aside SFINAE for the moment: a failed concept requirement results in an ill-formed program and a compilation failure.

On the other hand, the only part of C++ that could possibly "know" that your c does not "really" point to Base is dynamic_cast, which gets evaluated at runtime. As far as everything else in C++ goes, your c points to a Base instance, and that's the end of that discussion.

So, to summarize, as far as everything here that gets evaluated at compile time is concerned, your c points to a Base and there's nothing else that concepts can work with, that will indicate anything else.

Related