I have a relatively simple concept definition of a container type which takes in a specific value type:
template <typename T>
concept FooContainer = requires(T cont){
std::begin(cont);
std::end(cont);
requires std::is_same_v<typename T::value_type, Foo>;
};
And I would like to define a function that can take in two arguments, each being any container type that satisfy this concept. So far I have
void func(const FooContainer auto& cont1, const FooContainer auto& cont2){
// ...
}
This works fine and I can pass in any lvalue or rvalue I want into either cont1 or cont2, as I think C++ automatically binds a const lvalue reference to an rvalue parameter. However, I am wondering how perfect forwarding can be utilized here, so that the value categories can be automatically forwarded into the function.
I knew that forwarding references can only be used in a templated function, but this gets a bit confusing for me as the parameters are already templated concepts...
I tried adding && at different places: i.e. in the template typename T for the concept, but not sure exactly what it does.
Your func is a function template.
A forwarding reference is a parameter of type T&& where T is a template argument. I removed a bit of cruft from your code to concentrate on the essential:
#include <type_traits>
#include <iostream>
struct Foo {};
template <typename T>
concept FooContainer = requires(T){
requires std::is_same_v<typename std::remove_cvref_t<T>::value_type, Foo>;
};
struct Container {
using value_type = Foo;
};
void bar(const Container&) { std::cout << "hello &";}
void bar(Container&&) { std::cout << "hello &&"; }
void func(FooContainer auto&& cont1, FooContainer auto&& cont2){
bar(std::forward<decltype(cont1)>(cont1));
bar(std::forward<decltype(cont2)>(cont2));
}
int main() {
Container c;
func(c,Container{});
}
Output:
hello &hello &&
Note that you have to decide if your concept should match values or references or both. Thanks to Jarod42 for pointing that out. I added std::remove_cvref to accept both.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With