Is it possible to enable/disable a pure virtual function with `requires` clause?
Asked Answered
P

1

5

I have an adapter class which handles classes of the same concept.

Now, I want that adapter, based on template parameter RO (read only) to disable pack(). But I don't know if that is not supported in pure virtuals or just I write it wrongly.

template<bool RO>   // means read only functionality
class Adapter
{
    struct AbstractAdapter
    {
        virtual ~AbstractAdapter() = default;
        virtual void unpack() = 0;
        virtual void pack() = 0 requires (!RO);   // compile ERROR!! ERROR!! ERROR!!
    };


    template<typename T> requires (Reader<T> || Writer<T>)
    struct TemplateAdapter : public AbstractAdapter
    {
        virtual void unpack()
        {
            if constexpr (!Reader<T>) throw UnsupportedOperationEx{};
            else client.unpack();
        }
        virtual void pack() requires (!RO)
        {
            if constexpr (!Writer<T>) throw UnsupportedOperationEx{};
            else client.pack();
        }

        T client;
    };

public:
    void unpack() { client->unpack(); }
    void pack() requires(!RO) { client->pack(); }

private:
    AbstractAdapter *client;
};
Paranoid answered 26/7, 2020 at 19:49 Comment(2)
What's the point of dynamic polymorphism when you're also using static polymorphism?Pasteurizer
@NicolBolas: I've done the same in the past - there are times when e.g. the packing side knows the static types and has no need of virtual dispatch, but the unpacking side wants to use runtime polymorphism generally, though it might occasionally group objects by runtime type or prefer to branch once then perform a lot of operations, wanting static polymorphism. There can also be times when data's arriving over the network or via shared memory and therefore can't have space for or properly populated pointers to VDTs, so a polymorphic adapter like this (when finished) is convenient.Proterozoic
P
7

In the C++20 standard, 11.7.2 [class.virtual] paragraph 6 says:

A virtual function shall not have a trailing requires-clause (9.3). *[Example:

struct A {
    virtual void f() requires true;
         // error: virtual function cannot be constrained (13.5.2)
};

— end example]

It's more verbose, but you could instead use std::conditional to select between a ReadOnly and a ReadWrite adapter heirarchy. (Avoid multi-character identifiers using uppercase [with or without uniderscores) - best practices leaves them for preprocessor use).

Proterozoic answered 26/7, 2020 at 20:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.