2015-01-01 3 views
0

Я читал хороший учебник по ссылкам lvalue/rvalue. Если я правильно понял, когда существует дедукция типа, то что-то вроде T&& может принимать как lvalue, так и rvalue.Ссылка на C++ для LValue и Rvalue без вывода типа

Но есть ли способ достичь этого без общего класса? Я бы хотел избежать дублирования всех моих методов для принятия как lvalues, так и rvalues. И, конечно, избегайте пропуска больших объектов по стоимости.

+0

Почему вы не хотите типа вычет? – 0x499602D2

+1

Потому что мне это не нужно. В моем классе нет ничего общего. – Shepard

+1

Вместо этого используйте макрос. – cqdjyy01234

ответ

2

Ссылки r-value в основном используются в move-constructor и присваивании перемещения.

Для регулярного метода, вы можете придерживаться только одного типа ссылки:

  • только для чтения параметра (без копирования), константная ссылка достаточно.

  • , если вы должны сделать копию, вы можете взять ваш аргумент по значению и использовать std::move:

Пример:

class Test 
{ 
public: 

    void displayString(const std::string& s) const { std::cout << s << m_s; } 

    void setString(std::string s) { m_s = std::move(s); } 

private: 
    std::string m_s; 
}; 
+0

Что делает 'std :: move' точно? скопировать непосредственно параметр внутри 'm_s' вместо' s'? – Shepard

+0

'std :: move' выполнить приведение к r-значению.' std :: string' предоставляет move-assign, который будет * украсть * ресурс из 's' – Jarod42

+0

Итак, целевой класс (в моем случае glm :: vec3) должен поддерживать семантику перемещения, чтобы сделать это, правильно? – Shepard

1

Если функция, которую вы реализуете не нужно RValue semantic, то вы можете просто передать аргумент по ссылке или по постоянной ссылке.

Однако, если вы можете воспользоваться rvalues ​​и не хотите дублировать свой код, вы можете перейти по значению и перенести результат. Это должно быть почти таким же эффективным и может быть более удобным, чем дублирование кода или реализация с универсальными ссылками.

Этот ответ показывает технику: Should all/most setter functions in C++11 be written as function templates accepting universal references?

// copy, then move 
void set_a(A a_) { a = std::move(a_); } 
+3

* «Это должно быть почти таким же эффективным и может быть более удобным для обслуживания». * Это зависит от варианта использования. [Herb Sutter утверждает] (http://youtu.be/xnqTKD8uD64?t=51m8s), что для setter-подобных функций pass-by-const-ref является разумным дефолтом (все еще в C++ 14), с опцией добавления pass-by-rvalue-ref позже. – dyp

+0

@ dyp Правильно, я пояснил, что я имел в виду «более поддерживаемый, чем универсальные ссылки или дублирование кода». Если вы можете просто избежать этого, и простой const-ref достаточно хорош, я полностью согласен с вашими аргументами. –

+0

Я не совсем понимаю, о чем вы говорите, «более удобной, чем [..] реализация с использованием универсальных ссылок». Что делает такое решение менее ремонтопригодным? – dyp

 Смежные вопросы

  • Нет связанных вопросов^_^