LINUX.ORG.RU

Значение по-умолчанию для ссылки на итератор

 ,


0

1

Всем здрасте. Господа, подскажите, пожалуйста, как можно задать значение по-умолчанию для аргумента it.

//...
class MyClass
{
public:
    MyClass();
    int setBase(const string &str, string::iterator &it /* = ЧТО? */);
//...
};


Последнее исправление: v0r0n (всего исправлений: 2)

задать то можно, но работать не будет в общем случае. Передавать нужно всегда пару, начало и конец.

mashina ★★★★★
()

тебе нужен валидный итератор, чтобы передавать как default value для ссылки.

x0r ★★★★★
()
Ответ на: комментарий от mashina

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

v0r0n
() автор топика
Ответ на: комментарий от x0r

Где его взять? Пробовал так:

int setBase(const string &str, string::iterator &it = string().begin());
Но компилятор матерится на то, что begin() возвращает rvalue.

v0r0n
() автор топика
Ответ на: комментарий от v0r0n

Лучше перегрузить. Но если хочется, то можно как-то так

//...
class MyClass {
public:
    static const string  null_str;

    MyClass();
    int setBase(const string &str, string::iterator &it = null_str.begin());
};

далее в коде смотришь, если таки итератор на «нулевую» строчку, то считаешь что его нет

mashina ★★★★★
()

Возвращаемые параметры с дефолтными значениями делаются именно так

int setBase(const string &str, string::iterator * it = nullptr);

А стилистически правильно будет бросать исключение или возвращать 0 (или -1, что там) и устанавливаеть где-нибудь код ошибки.

E ★★★
()
Ответ на: комментарий от v0r0n

со static const пример привели. я бы передавал size_t индекс, вместо итератора.

x0r ★★★★★
()
Ответ на: комментарий от x0r

Советую изучить разницу между указателями и ссылками и разобраться, почему «дефолтное значение для неконстантной ссылки» - это оксюморон.

E ★★★
()
Ответ на: комментарий от E

Ну, а что такого в том, что я собираюсь использовать эту ссылку, грубо говоря, для получения кода ошибки?

v0r0n
() автор топика

Фигней какой-то страдаете. Но вот такое у меня скомпилировалось:

void do_some(string::iterator i = string::iterator(nullptr))
{
    printf("OMG!!!\n");
}

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

В аргументах должна быть именно ссылка (с указателями заморочено выходит), для возврата значения из функции.

v0r0n
() автор топика
Ответ на: комментарий от v0r0n

В аргументах должна быть именно ссылка (с указателями заморочено выходит), для возврата значения из функции.

Склонен считать, что таких аргументов вообще не должно быть.

pathfinder ★★★★
()
Ответ на: комментарий от E

да там не указатель, там итератор не нужен. указатель на итератор это вообще. осталось только в shared_ptr завернуть.

x0r ★★★★★
()
Ответ на: комментарий от v0r0n

Тебе тоже не помешает разобраться с указателями и ссылками.

Нельзя сделать неконстантную ссылку на временный объект. На константный - можно, она не сможет использоваться после выхода из функции. А этот nullstr.begin(), который выше предлагают, даже если бы и скомпилировался, уничтожился бы по выходу из функции, а ссылка, меж тем, остаётся. На что она будет указывать?

Стандартные пути возврата ошибки из функции я привёл, и не один даже. Не изобретай велосипеды, особенно, когда не умеешь.

E ★★★
()
Ответ на: комментарий от x0r
template<class T>
int setBase(const string &str, T * it = nullptr);
E ★★★
()
Ответ на: комментарий от E

Нельзя сделать неконстантную ссылку на временный объект.

Правда твоя. С удивлением обнаружил, что ЭТО скомпилировалось:

void do_some(string::iterator&& i = string::iterator(nullptr))
{
    printf("OMG!!!\n");
}
pathfinder ★★★★
()
Ответ на: комментарий от E

Внутри функции переопределяю эту ссылку на str.begin(), так что она не пропадает.

v0r0n
() автор топика
Ответ на: комментарий от pathfinder

Не годится, я его ещё не осилил...

v0r0n
() автор топика
Ответ на: комментарий от mashina

А как rvalue и const_iterator связаны? Проблема в том, что & от rvalue не проходит и замена iterator на const_iterator ничего не изменит. Попробовал, то же самое.

v0r0n
() автор топика
Ответ на: комментарий от v0r0n

const_iterator связан с тем, что null_str константен и на него можно получить только const_iterator. А c rvalue связано отсутствие &. Там два изменения.

mashina ★★★★★
()
Ответ на: комментарий от mashina

Мне же нужно смотреть значение it после вызова функции, если оно rvalue, то я ничего и не вытащу наружу...

v0r0n
() автор топика
Ответ на: комментарий от v0r0n

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

mashina ★★★★★
()
Ответ на: комментарий от mashina

Вообще данный вариант прошёл как нужно

//...
class MyClass {
public:
    MyClass();
    int setBase(const string &str, string::iterator &it = itDef);

private:
    static string::iterator itDef;
};
Но здаётся мне, лучше не городить эти костыли, а просто перегрузить функцию... Как считают гуру?

v0r0n
() автор топика
Ответ на: комментарий от v0r0n

Вот если б не нужно было б объявлять вот это:

static string::iterator itDef;

v0r0n
() автор топика
Ответ на: комментарий от E

Спасибо за наводку, не знал про константные ссылки на временные объекты.

v0r0n
() автор топика

Либо используй указатель либо перегрузи функцию.

slovazap ★★★★★
()
Ответ на: комментарий от v0r0n

it, по задуманному, будет содержать в себе положение в строке, где парсер обнаружил ошибку.

Используй int и не выпендривайся

yoghurt ★★★★★
()
Ответ на: комментарий от v0r0n

Да вообще в никуда может указывать, этот аргумент должен быть не обязательным

в никуда может указывать

Ссылка в принципе не может «в никуда» указывать. Тебе правильно советуют про указатель или перегрузку.

no-such-file ★★★★★
()
int setBase(const string &str)
{
  string::iterator it = /* ЧТО */;
  return setBase(str, it);
}

int setBase(const string &str, string::iterator &it)
{
  //...
}
emulek
()

В самом stl для таких дел прекрасно используется size_t с 0 или npos в качестве значения по умолчанию. Зачем усложнять себе жизнь на ровном месте?

Gvidon ★★★★
()

Тред не читал. Тс, иди читай книжки по спп. /thread.

nanoolinux ★★★★
()
Ответ на: комментарий от x0r

эх, а в петоне можно было бы замкнуть первый setBase на второй...

в сишке тоже можно, но это сахар, и лучше это сделать явно. ИМХО. Я предоставил своё решение, оно не оптимально для всех случаев. Но я стараюсь делать именно так, ибо такой код легче сопровождать.

Проблема в том, что если сделать это одной функцией, то я не очень хорошо понимаю, как это будет реализовано в машинном коде. Ещё раз, это только моё мнение.

emulek
()

Всем спасибо, вопрос исчерпан.

v0r0n
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.