Почему использовать 'n.pos'no - рекомендуемо?

В одном из ответов, которые дали мне, в конце ее они советовали мне не использовать s.npos и использовать взамен string::npos.

Как я не знаю, что много C ++ я хочу попросить их, если они могут объяснять мне, из-за которого более рекомендуемый 1er метод и не 2-ой.

Дериват этого вопроса.

5
задан 13.04.2017, 16:00
2 ответа

npos определен внутри класса шаблон std::basic_string как:

static const size_type npos = -1;

А именно: он - статический член класса и из-за этого он не принадлежит никакой инстанции, если не в класс; использовать нотацию доступа к члену скрытого класса этот факт и может давать место в путаницу (как уже прокомментировал Хосе Антонио Дура Ольмос).

Технические детали на статических членах.

Согласно стандарту C ++ в точке §9.4.2.1 (перевод и выделенный мои):

9.4.2 Данные член статические

  1. Информация очевидный член как static он не составляет часть суб-объектов класса. Если информация статический член объявлен cmo thread_local будет существовать копия члена из-за каждого трэда. Если информация статический член не delcarado как thread_local будет существовать инстанция члена, которая будет иметься всеми объектами класса.

Самая важная часть выделенного - тот факт, что статический член не составляет часть суб-объектов класса. А именно: в случае, который занимает нас npos он не составляет часть никакой инстанции std::basic_string если не, что принадлежит классу, если и как следствие все инстанции соглашаются на ту же копию изменчивая член.

Сам стандарт показывает, что возможно соглашаться на статических членов классов (переменные или функции) используя нотацию доступа член в точке §9.4.2 (перевод и выделенный мои):

9.4 Статические члены

  1. Статический член s класса X смоги быть соглашенным используя выражение X::s; не необходимо использовать синтаксис доступа к члену класса, чтобы относиться к статическому члену. Статический член может быть соглашенным используя синтаксис доступа к члену класса, в этом случае выражение объекта оценено [Пример:

    struct process {
        static void reschedule();
    };
    process& g();
    
    void f() {
        process::reschedule(); // CORRECTO: no se necesita instancia
        g().reschedule(); // llamada a g()
    }
    

    конец примера]

Так что статические члены класса могут соглашаться со статической нотацией (Clase::miembro) или с нотацией члена инстанции (Clase c; c.miembro)..., о котором нужно спрашивать:

Почему нотация должна бы быть предпочтенной напротив другой?

Предполагая, что у нас есть эти две структуры:

struct A { int a{};        };
struct B { static int b{}; };

Давайте видеть, как они функционируют в коде:

A a; B b; // Instanciamos A y B.
std::cout << A::a << '\n'; // Error de compilacion
std::cout << a.a  << '\n'; // Muestra 0
std::cout << B::b << '\n'; // Muestra 0
std::cout << b.b  << '\n'; // Muestra 0

Член a A только существуй, когда инстанция A, отсюда следует, что, попробовав читать Вашу стоимость, появилась ошибка компиляции. С другой стороны член b B существуй с или без инстанции B.

Ввиду того, что нотация Clase::miembro только функционируй с членами estáticos1 и нотация instancia.miembro или instancia->miembro функционируй со статическими членами и с членами инстанции мы встречаемся, что вторая нотация может быть неясной в то время как первая точная.

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

В каком-то случае может быть выгоднее нотация instancia.miembro_estatico?

Мне сложно намереваться о какой-то ситуации, в которой, соглашаться на статического члена посредством нотации accesoa, член класса был бы лучшим выбором. Самым похожим был бы характерный код, в котором использованные классы были бы ясно неясными, и из-за этого было возможно доставать пользу двусмысленности доступа посредством точки (.) или срази стрелой (->):

struct Banana { int calorias_por_gramo{};        };
struct Papaya { static int calorias_por_gramo{}; };

template <typename FRUTA>
void muestra_calorias_de(FRUTA f, float gramos)
{
    std::cout << "Tiene " << f.calorias_por_gramo * gramos << "calorías\n";
}

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

Если нотация может быть неясной: почему она позволена?

В первых версиях C ++ единственные синтаксисы доступа к членам (статические или не) это была точка (.) и стрела (->); ввиду того, что не существовал конкретный синтаксис, чтобы соглашаться на данные, которые не требовали инстанции, программисты использовали доступное единственное:

struct B { static int b{}; };
std::cout << (B*(0))->b << '\n'; // Muestra 0

Предыдущий код преобразовывает стоимость 0 в указателе в класс B и непосредственно вслед согласись посредством стрелы -> в члена b вышеупомянутой инстанции; в существо b статический член не необходим оценивать указатель, который обозначается в 0 и он не отпускает ошибку во время выполнения.

Когда C ++ он эволюционировал и присоединил оператор :: не был удален предыдущий синтаксис.

Заключение.

Сам стандарт C ++ позволяет (возможно в пользу исторических мотивов) доступ к статическим членам объектов посредством нотации не статических членов; но эта нотация неясная, так как они могут запутываться с доступом к не статическим членам, чтобы предотвращать вышеупомянутую путаницу, советуется использовать нотацию Clase::miembro_estático для desambiguar.


1Esa нотация функционирует в других контекстах (например указатели в членов), но это другая тема.

3
ответ дан 24.11.2019, 13:29

Когда программист видит Clase::miembro знай, что соглашаются на статического члена класса. Что значит, что этот член не присоединен ни с каким объектом, возможно призывать это несмотря на то, что не будет создан никакой объект этого Класса.

Когда он видит objeto.otroMiembro знай, что возможно, что соглашаются на члена instacia или на статического члена. Но ввиду того, что есть номенклатура, которая исключительная для статических членов обычное, он состоит в том, чтобы оставлять эту другую номенклатуру только для членов инстанции. И если ты работаешь с людьми, которые ты знаешь, что такая программа оказывается более легкой и быстрой, понимать Ваш код.

Говорится о соглашении. Не письменное правило (или да написанная в неких путеводителях стиля), который облегчает trabajo en equipo. Следовательно это рекомендация стиля. На уровне объектного кода нет различия между вещью и другой.

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

2
ответ дан 24.11.2019, 13:29