他の関数を呼び出すテンプレート関数に 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
持つメンバー関数があります。行 (1) により、次のエラーが発生します。const int&
a_caller
'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
ですか? 2 番目の質問は、なぜこれが std::make_unique で起こらないのかということです。次のコードは同じように見えますが、コンパイラーはコンストラクターの引数の型を問題なく推測します。
struct A
{
A(const int& i) { }
};
int main()
{
int i = 42;
auto aptr = std::make_unique<A>(i);
}