Мне интересно, какое правило разрешения метода перегрузки было применено здесь.
Моя цель состояла в том, чтобы создать новый временный экземпляр с помощью конструктора копирования, а затем передать этот объект методу, чтобы передать ссылку на r-значение.
И есть перегруженные методы, которые принимают l-значение, r-значение, поэтому я ожидал, что будет вызван перегруженный метод r-значения, но это не так.
class Kdy {
public:
Kdy() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
Kdy(Kdy&&) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
Kdy(const Kdy&) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void DoAction(const Kdy&) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void DoAction(Kdy&&) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
}; // Kdy
int main() {
Kdy kdy1;
Kdy kdy2;
// DoAction(const Kdy&), Why??
// kdy1.DoAction(Kdy(kdy2))
kdy1.DoAction({kdy2});
// Then why this works?
// After copy-ctor, DoAction(Kdy&&) was invoked.
kdy1.DoAction({ {kdy2} });
// Then why this dosen't compile?
// Since { {kdy2} } becomes Kdy&&
// { { {kdy2} } } should be Kdy(Kdy&&)
// kdy1.DoAction({ { {kdy2} } });
return 0;
}
Я прочитал перегрузкуссылочный документ несколько раз, но он мне наполовину ясен https://en.cppreference.com/w/cpp/language/overload_resolution
Кажется, что после сбора набора методов-кандидатов компилятор принимает решение, какой метод лучше всего подходит по приоритету сопоставления.
Итакочевидно, если есть несколько методов, принимающих std::initializer_list<Kdy>
в качестве параметра, то эти методы выбираются(Я проверил это)
В таком случае, если точное совпадение подписи не удалось, какое правило перегрузки разрешения было применено в этом контексте?Что заставило компиляцию думать, что {kdy2}
лучше подходит для const Kdy&
, чем для Kdy&&
?
Кроме того, почему { { { kdy2 } } }
нельзя интерпретировать как Kdy(Kdy&&)
?
Пожалуйста, скажитесвет на этого бедного парня.Спасибо!