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;
};
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).