2つのオーバーロードされた関数があります。1つはL値を取り、もう1つはR値を取ります。目的は、関数を次のように呼び出すことができるようにすることです。
Obj obj;
foo(obj);
また:
foo(Obj());
だから、私は2つのオーバーロードされた関数を書きます:
template <class T>
void foo(T& v)
{
/* ... function body code goes here ... */
}
template <class T>
void foo(T&& v)
{
foo(v);
}
int main()
{
foo(int(5));
}
R値の過負荷は、L値の過負荷に委任する必要があるだけです。私がそれを理解する方法では、関数の本体に入ると、特にまたはv
を使用しない限り、を使用するとL値の参照が得られます。したがって、R値のオーバーロード内で呼び出すと、(繰り返しではなく)L値のバージョンが自動的に呼び出されます。std::move
std::forward
foo(v)
しかし、コンパイラはあいまいさについて不平を言います。
test.cpp: In function ‘void foo(T&&) [with T = int]’:
test.cpp:305:12: instantiated from here
test.cpp:299:2: error: call of overloaded ‘foo(int&)’ is ambiguous
なぜこれが曖昧なのかわかりません。R値のオーバーロード内での呼び出しfoo()
は、L値バージョンを明確に呼び出す必要があります。では、なぜこれはコンパイルされないのですか?