我遇到了一个问题,即在调用其他函数的模板函数中传递const ref参数。请考虑以下代码:
struct A
{
void foo(const int& i) { }
};
template <class ...Args>
void a_caller(A& a, void(A::*f)(Args...), Args&& ...args)
{
(a.*f)(std::forward<Args>(args)...);
}
int main()
{
int i = 42;
A a;
a_caller(a, &A::foo, i); // (1) compiler error
a_caller<const int&>(a, &A::foo, i); // (2) ok
}
所以,我有一个成员函数A::foo
,其中有一个const int&
参数,我想在包装器a_caller
中调用它。第一行(1)会导致以下错误:
'void a_caller(A &,void (__thiscall A::* )(Args...),Args &&...)' : template parameter 'Args' is ambiguous
see declaration of 'a_caller'
could be 'const int&'
or 'int&'
我的第一个问题是为什么会出现这种情况?我给编译器一个非重载函数A::foo,它为什么不能从中推导出Args
?
第二个问题是为什么std::make_unique不会出现这种情况?以下代码看起来对我来说是相同的,但编译器推导构造函数参数类型时却没有问题:
struct A
{
A(const int& i) { }
};
int main()
{
int i = 42;
auto aptr = std::make_unique<A>(i);
}