Переместить семантику и вернуть константные значения

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

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 ответа

Решение

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

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

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

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

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

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

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

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

Другие вопросы по тегам