问题描述
我考虑了以下 2 个执行相同操作的代码段。在第一种情况下,我不使用通用引用,因此我必须编写函数 set
两次。在第二种情况下,使用通用引用我可以编写一次函数,但类的用户必须明确指定传递给函数 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
的类型。