C++概念与完美转发

问题描述 投票:0回答:1

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

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
中,但不确定它到底有什么作用。

c++ templates c++20 c++-concepts perfect-forwarding
1个回答
3
投票

您的

func
是一个函数模板。

转发引用是

T&&
类型的参数,其中
T
是模板参数。我从您的代码中删除了一些多余的内容,以专注于本质:

#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{});
}

输出

hello &hello &&

请注意,您必须决定您的概念是否应该与值或参考文献或两者相匹配。感谢 Jarod42 指出了这一点。我添加了

std::remove_cvref
来接受两者。

© www.soinside.com 2019 - 2024. All rights reserved.