C++ Logo

std-discussion

Advanced search

Question regarding how to declare templated functions inside a concept declaration

From: Marios Staikopoulos <marios_at_[hidden]>
Date: Mon, 18 Apr 2022 01:08:23 +0000
Hi, I have a question regarding how to declare a templated function, whose type is of another Concept.

I believe the easiest way to explain this would be to use an example, and I will try to omit irrelevant info, so the code will be incomplete:

First, a simple buffer concept:

```
template< typename T>
concept Buffer = requires( T buf, const T cbuf, size_t s)
{
               { cbuf.HasData() } -> std::same_as<bool>;
               { buf.GetData() } -> std::same_as<uint8_t*>;
               { cbuf.GetSize() } -> std::same_as<size_t>;
};
```

My confusion/issue now comes with how to use the above Buffer concept as a template constraint for another concept, IE:

```
template< typename T >
concept EncryptionKey = requires (const T key)
{
               // pseudo code, as I am unaware of how to proceed

               {
                              template<Buffer B>
key.template EncryptFast<Buffer>(Buffer& b) // not sure where even "b" would come from
} -> std::same_as<bool>;


               {
                              template<Buffer B1, Buffer B2>
                              key.template EncryptFast<B1, B2>(Buffer& out, const Buffer& in)
               } -> std::same_as<bool>

};
```

Basically, I am trying to enforce that the concept EncryptionKey has templated methods EncryptFast with constraints on their template parameters to be of concept Buffer.

The closest I've gotten, however incomplete is this:

```
template<typename T, typename B>
concept EncryptionKey = requires(const T key, B& buf, const B& c_buf)
{
               requires Buffer<B>;

               { key.EncryptFast(buf) } -> std::same_as<bool>;
               { key.EncryptFast(buf, c_buf) } -> std::same_as<bool>;
};
```

However, this is not what I am looking for, as this requires me to be upfront and inform it of the dependent typename B at template definition, like so:

```
template<Buffer B, EncryptionKey<B> K>
void EncryptBufferHelper(B& buf, const K& key)
```

which is fine, assuming we are copying to one exact type of buffer, but what about this:

```
template<Buffer B1, Buffer B2, Encryptionkey<???> K>
void EncryptBufferHelper(B1& buf1, const B2& buf2, const K& key)
{
               key.EncryptFast<B1, B2>(buf1, buf2);
}
```


I can't seem to find any info at all regarding this issue, and was wondering if there is even reference to this in the standard, or if anyone has achieved something similar.

Regards,
Marios S

Received on 2022-04-18 01:08:27