template<typename ...T>
auto makeGroup(T&&...t)
{
return Group<T...>(std::forward<T>(t)...);
}
void use()
{
std::string s{ "Todo" };
int a = 7;
auto h = makeGroup(a, s);
}
The other problem is more subtle. Here is a minimal example.
1 2 3 4 5 6 7 8 9 10 11 12 13
template<typename T> struct Group
{
explicit Group(const T&) {}
explicit Group(T&& ) {}
};
template<typename T> auto makeGroup(T&& t) { return Group<T>(t); }
int main()
{
int a = 7;
auto y = makeGroup(a);
}
In this case makeGroup attempts to instantiate Group<int&>. The two constructors are ambiguous because these assertions hold:
1 2 3
using Q = int&;
static_assert(std::is_same_v<Q, Q const&>);
static_assert(std::is_same_v<Q const&, Q&&>);
Initially Q const& can be thought of a "reference to const reference to int", which after [dcl.ref].1 is applied and references are collapsed, is adjusted to int&: http://eel.is/c++draft/dcl.ref#1.sentence-3