具有通用引用的 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
的类型。
我考虑以下 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
的类型。