具有通用引用的 C++ 完美转发可防止类型推导?

c++ perfect forwarding with universal reference prevents type deduction?

我考虑以下 2 个片段,它们做同样的事情。在第一种情况下,我没有使用通用引用,所以我必须将函数 set 写两次。在第二种情况下,使用通用引用我可以编写函数一次,但是 class 的用户必须明确指定传递给函数 set 的类型。有没有什么技巧可以兼顾两者的优势?

#include <iostream>

struct A {};

template<typename T>
struct B {

    void set(const A& a) {
        a_=a;
    }
    
    void set(A&& a) {
        a_=std::forward<A>(a);
    }

    A a_;
};

int main() {

    B<A> b;
    A a;

    b.set({});
    b.set(a);

    return 0;
}

#include <iostream>

struct A {};

template<typename T>
struct B {

    template<typename U>
    void set(U&& a) {
        a_=std::forward<U>(a);
    }
    
    A a_;
};

int main() {

    B<A> b;
    A a;

    b.set(A{}); // here I can't do b.set({}) because the template parameter U would be undefined
    b.set(a);

    return 0;
}

在这种情况下,您可以将默认值添加到 U 模板参数,例如

template<typename U = T>
void set(U&& a) {
    a_=std::forward<U>(a);
}

现在,如果它可以推断出类型,例如没有类型的 {},那么它将回退到使用 T 作为 U 的类型。