Я нашел ссылку ниже, в которой говорилось, что «справочный интерфейс lvalue и rvalue может объединяться в один». Передать lvalue в rvalue
но когда я беру это например. появилась ошибка компиляции cannot bind ‘std::string {aka std::basic_string}’ lvalue to ‘std::string&& {aka std::basic_string&&}’
. Ниже моя реализация.
#include <iostream>
#include <string>
using namespace std;
void g(string &&b) {
cout << b << endl;
}
void g(const string &b) {
cout << b << endl;
}
void f(string &&a) {
g(std::forward<string>(a));
}
int main()
{
f("1122");
string a("222");
f(a);
return 0;
}
Я имею в виду, что «void f(string &&a)» и «void f(const string &a)» могут сочетаться в одном. Затем нам просто нужно вызвать "void f(string &&a)", который может получать как ссылку на rvalue, так и lvalue по предисловию вперед.
--------- Добавить описание
это может быть звонок universal reference
Чтобы объединить ссылку r-значения и ссылку l-значения в одну ссылку, вам нужно использовать так называемую универсальную ссылку. Они определены в C++ через auto &&
или шаблон со ссылкой &&. См. например Что такое семантика движений? , хотя, в исключительных случаях, я думаю, вы найдете более доступные объяснения вне stackoverflow. Найдите «универсальный справочник C++».
Теперь вернемся к вашему коду. Все, что вам нужно, это:
template <typename T>
void f(T &&a)
{
g(std::forward<string>(a));
}
Вот и все. Универсальная ссылка, определенная с помощью шаблона и ссылки &&. Обратите внимание, что мне пришлось заменить string
на T
.
Однако простота — наш лучший друг. Если вам не нужен шаблон, почему бы не воспользоваться старой хорошей ссылкой на const?
void f(const string & a)
{
g(a);
}
Для меня это предпочтительное решение.
спасибо за четкий ответ! но у меня есть класс очереди, который уже использует A universal reference defined via a template plus a &&-reference
, но он может успешно передать rvalue, но не может передать lvalue. в чем может быть проблема? это функция-член класса с шаблоном.
@ dahohu527, я думаю: у вас есть шаблон класса template<class T> class my_class { ... };
с функцией-членом void foo(T&&)
. В этом случае T&&
— это не универсальная ссылка, а просто ссылка на rvalue, а ссылки на rvalue не могут привязываться к lvalue. Если бы у вас был template<class S> foo(S&&)
, S&&
был бы универсальной ссылкой.
@Evg Да, ты прав, это действительно трудно понять. Эта статья очень помогает. isocpp.org/blog/2012/11/…
Какому ответу на связанный вопрос вы пытаетесь следовать? Тот, который использует шаблон (в отличие от вашего кода) или тот, который направляет выполнение на унифицированную функцию (ваш код исходит из унифицированной функции)? Ни то, ни другое не соответствует тому, что вы сделали, и вы связались с вопросом, а не с конкретным ответом...