C++ Logo

std-discussion

Advanced search

Re: Question regarding how to declare templated functions inside a concept declaration

From: Marios Staikopoulos <marios_at_[hidden]>
Date: Thu, 28 Apr 2022 17:58:07 +0000
I want to bring this back up – I did manage to get this working with an Archetype + the concept. But this seems so wrong – you basically must define a concept and then define a dummy class that constrains the template. This basically looks like a redundant declaration in code, and just adds more confusion.

It seems like a hole if we cannot declare templated concept constraints inside of a concept – I can’t see a reason why this should be a limiting factor.

This seems like a very realistic requirement for containers as well – something like the below:

template<typename T>
concept Iterator = requires() {
   …
};

template<typename T>
concept Container = requires(T container, concept Iterator itr) {
    { container.begin() } -> std::same_as<Iterator>;
    { container.end() } -> std::same_as<Iterator>;
};

template<typename T>
concept IterationAlgorithm = requires(T algo) {

    template<typename IT>
    requires Iterator<IT>
    { void apply(IT begin, IT end) } -> std::same_as<void>;

};

From: Edward Catmur <ecatmur_at_[hidden]om>
Sent: Monday, April 18, 2022 8:42 AM
To: std-discussion_at_[hidden]
Cc: Marios Staikopoulos <marios_at_staik.net>
Subject: Re: [std-discussion] Question regarding how to declare templated functions inside a concept declaration

It sounds like what you're after is archetypes: https://en.cppreference.com/w/cpp/language/archetype

You can combine both solutions of course - default the Buffer template parameter(s) to BufferArchetype, allowing you to both check the argument with a specific type and in general.

On Mon, 18 Apr 2022, 02:08 Marios Staikopoulos via Std-Discussion, <std-discussion_at_[hidden]<mailto:std-discussion_at_[hidden]>> wrote:
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
--
Std-Discussion mailing list
Std-Discussion_at_lists.isocpp.org<mailto:Std-Discussion_at_[hidden]>
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion

Received on 2022-04-28 17:58:12