I consider the following 2 snippets which do the same thing. In the first case, I don't use a universal reference, and so I have to write the function set
twice. In the second case, with a universal reference I can write the function once, but the user of the class has to specify explicitly the type passed to the function set
. Is there a trick to get both advantages?
#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;
}
and
#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;
}
In this case, you can add a default value to the U
template parameter like
template<typename U = T>
void set(U&& a) {
a_=std::forward<U>(a);
}
and now if it can deduce the type, like with {}
which has no type, then it will fall back t using T
as the type for U
.