C++概念与完善转发

vs3odd8k  于 2023-08-09  发布在  其他
关注(0)|答案(1)|浏览(124)

我有一个相对简单的容器类型的概念定义,它接受一个特定的值类型:

template <typename T>
concept FooContainer = requires(T cont){
    std::begin(cont);
    std::end(cont);
    requires std::is_same_v<typename T::value_type, Foo>;
};

字符串
我想定义一个函数,它可以接受两个参数,每个参数都是满足这个概念的任何容器类型。到目前为止

void func(const FooContainer auto& cont1, const FooContainer auto& cont2){
        // ...
    }


这很好用,我可以将任何左值或右值传入cont1或cont2,因为我认为C++会自动将const lvalue reference绑定到rvalue参数。然而,我想知道如何在这里使用完美的转发,以便值类别可以自动转发到函数中。
我知道转发引用只能在模板化函数中使用,但这让我有点困惑,因为参数已经是模板化的概念了...
我尝试在不同的地方添加&&:即,在概念的模板typename T中,但不确定它到底做了什么。

u4dcyp6a

u4dcyp6a1#

你的func是一个函数模板。
转发引用是T&&类型的参数,其中T是模板参数。我从你的代码中删除了一点cruft,以专注于基本内容:

#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 &&


请注意,您必须决定您的概念是否应该匹配值或引用或两者。感谢Jarod42指出这一点。我添加了std::remove_cvref来接受两者。

相关问题