Почему этот вызов называют неоднозначным? - PullRequest
7 голосов
/ 08 апреля 2011

Почему этот вызов rvalue неоднозначен? Я могу иметь AA и AA &, и компилятор будет знать, что использовать AA&. Но когда я добавляю третий вариант, я получаю ошибку. Очевидно, что AA && - лучшая перегрузка, чем другие, например int, для int лучше, чем long. Почему это неоднозначно? Есть ли способ, которым я могу сохранить все 3 перегрузки и дать понять, какой я хочу? (Typecasting (AA&&) этого не сделает).

struct AA{
    void*this_;
    AA() { this_=this; }
    //not valid, use AA&, AA(AA a){ this_=this; }
    AA(AA&a){ this_=this; }
    AA(AA&&a){ this_=a.this_; }
};
void movetest(AA s) {}
void movetest(AA& s) {}
//This gets me the ambiguous error void movetest(AA&& s) {}
AA&& movetest() { return AA(); }
void MyTestCode2(){
    AA a;
    AA b(a);
    AA c = movetest();
    movetest(AA());
}

Ответы [ 2 ]

7 голосов
/ 08 апреля 2011

Я могу иметь AA и AA & и компилятор будет знать, чтобы использовать AA &

Да, в случае movetest (AA ()); , только movetest (AA) является жизнеспособным, поскольку ссылка (lvalue) на неконстантную связь не может быть привязана к значению. Однако говорят, что ссылка rvalue привязывает напрямую к временному. Таким образом, для разрешения перегрузки функции

void movetest(AA)
void movetest(AA&&)

равны, поскольку последовательности неявного преобразования , используемые для преобразования AA () в AA и AA && , соответственно равны , Первое не лучше, потому что прямое связывание ссылок также считается преобразованием идентичности.

2 голосов
/ 08 апреля 2011

Согласен с decltype.Это действительно ничем не отличается от этой неоднозначности C ++ 03/98:

struct AA {};

void movetest(AA s) {}
void movetest(AA& s) {}

int main()
{
    AA a;
    movetest(a);
}

test.cpp:9:5: error: call to 'movetest' is ambiguous
    movetest(a);
    ^~~~~~~~
test.cpp:3:6: note: candidate function
void movetest(AA s) {}
     ^
test.cpp:4:6: note: candidate function
void movetest(AA& s) {}
     ^
1 error generated.
...