Переместить семантику и вернуть константные значения - PullRequest
3 голосов
/ 21 августа 2011

У меня есть привычка (?!?!?) Возвращать все как "постоянное" значение.Вот так ...

struct s;

s const make_s();

s const &s0 = make_s();
s const s1 = make_s();

С операциями перемещения и ссылками на r-значения и следующими функциями ...

void take_s(s &&s0);
void take_s(s const &&s0);  //  Doesn't make sense

Я больше не могу писать ...

take_s(make_s());

Основная причина, по которой я начал использовать соглашение о возвращении константных значений, заключается в том, чтобы запретить кому-либо писать код, подобный этому ...

make_s().mutating_member_function();

Вариант использования следующий ...

struct c_str_proxy {
    std::string m_s;

    c_str_proxy(std::string &&s) : m_s(std::move(s)) {
    }
};

c_str_proxy c_str(std::string &&s) {
    return c_str_proxy(s);
}

char const * const c_str(std::string const &s) {
    return s.c_str();
}

std::vector < std::string > const &v = make_v();
std::puts(c_str(boost::join(v, ", ")));

std::string const my_join(std::vector < std::string > const &v, char const *sep);

//  THE FOLLOWING WORKS, BUT I THINK THAT IS ACCIDENTAL
//  IT CALLS
//
//      c_str(std::string const &);
//
//  BUT I THINK THE TEMPORARY RETURNED BY
//
//      my_join(v, "; ")
//
//  IS NO LONGER ALIVE BY THE TIME WE ARE INSIDE
//
//      std::puts
//
//  AS WE ARE TAKING THE "c_str()" OF A TEMPORARY "std::string"
//
std::puts(c_str(my_join(v, "; ")));

Похоже, что «возвращаемое значение константы» и ссылки на r-значения не смешиваются в этом конкретном случае использования.Это верно?

**Edit 0: Extra question...**

Объект все равно временный.Почему «const» должен препятствовать движению?Почему мы не можем переместить "постоянные" временные фильтры?

Ответы [ 3 ]

11 голосов
/ 21 августа 2011

У вас две противоречивые цели.С одной стороны, вы хотите предотвратить внесение изменений в возвращаемый объект, но , с другой стороны , вы хотите разрешить изменения (это и есть операция перемещения. Он изменяет исходный объект, крадет его внутренних ресурсов).

Вы должны принять решение.Вы хотите, чтобы объект был неизменным, или вы хотите, чтобы люди могли изменять его?

Для чего бы это ни стоило, я не вижу, что вы получите, возвращая const temporases в первомместо.Да, вы запрещаете людям вызывать на нем функцию-мутанта, но с чего бы вам ?В лучшем случае возможность сделать это может быть полезной, а в худшем - это ошибка, которую легко избежать.

И то, что вы делаете, на самом деле не имеет особого смысла.Весь смысл в временном состоит в том, что он скоро исчезнет, ​​поэтому кого волнует , если он будет изменен?

Вся идея, стоящая за ссылками на rvalue иСемантика перемещения заключается в том, что временные файлы являются временными, и поэтому их можно изменять, не причиняя вреда никому.

1 голос
/ 21 августа 2011

У вас могут возникнуть проблемы с выходом локальной переменной из области видимости.

c_str() возвращает указатель на внутренний буфер, поэтому, как только исходная переменная выходит из области видимости, указатель будет недействительным.

0 голосов
/ 21 августа 2011

В возвращаемом значении нет никакого семантического значения для квалификатора const.Если вы включите уровень предупреждения на вашем компиляторе, он будет выдавать предупреждение каждый раз, когда вы делаете это.

...