Замыкание накоротко C++ булевских переменных

Ничего себе. C++ никогда не прекращает удивлять меня своей странностью.

В шаблонном определении, дисквалифицированные имена больше не будут находить членов зависимой основы (как определено [temp.dep]/3 в стандарте C++). Например,

template <typename T> struct B {
  int m;
  int n;
  int f ();
  int g ();
};
int n;
int g ();
template <typename T> struct C : B<T> {
  void h ()
  {
    m = 0; // error
    f ();  // error
    n = 0; // ::n is modified
    g ();  // ::g is called
  }
};

необходимо сделать зависимого имен, например, путем добавления префикса их это->. Вот исправленное определение C:: h,

template <typename T> void C<T>::h ()
{
  this->m = 0;
  this->f ();
  this->n = 0
  this->g ();
}

Как альтернативное решение (к сожалению, не назад совместимый с GCC 3.3), можно использовать объявления использования вместо этого->:

template <typename T> struct C : B<T> {
  using B<T>::m;
  using B<T>::f;
  using B<T>::n;
  using B<T>::g;
  void h ()
  {
    m = 0;
    f ();
    n = 0;
    g ();
  }
};

Это - просто все виды сумасшедших. Спасибо, David.

Вот "temp.dep/3" раздел стандарта [ISO/IEC 14882:2003], к которому они обращаются:

В определении шаблона класса или члене шаблона класса, если базовый класс шаблона класса зависит от шаблонного параметра, объем базового класса не исследован во время неполного поиска имени или при определении шаблона класса или при участнике или во время инстанцирования шаблона класса или участника. [Пример:

typedef double A; 
template<class T> class B { 
    typedef int A; 
}; 
template<class T> struct X : B<T> { 
    A a; // a has typedouble 
}; 

имя типа A в определении X<T> связывает с именем определения типа, определенным в объеме глобального пространства имен, не к имени определения типа, определенному в базовом классе B<T>.] [Пример:

struct A { 
    struct B { /* ... */ }; 
    int a; 
    int Y; 
}; 
int a; 
template<class T> struct Y : T { 
    struct B { /* ... */ }; 
    B b; //The B defined in Y 
    void f(int i) { a = i; } // ::a 
    Y* p; // Y<T> 
}; 
Y<A> ya; 

участники A::B, A::a, и A::Y из аргумента шаблона A не влияют на привязку имен в [1 112].]

10
задан tinkertime 25 November 2009 в 18:44
поделиться

8 ответов

Нет, часть B == 2 не оценивается. Это называется оценкой короткого замыкания .

Редактировать: Как Роберт К. Картаино справедливо указывает , если логический оператор перегружен, оценка короткого замыкания не выполняется имеют место (как уже было сказано, я не понимаю, почему кто-то перегружает логический оператор).

20
ответ дан 3 December 2019 в 13:47
поделиться

Если оператор || не перегружен , второе выражение не будет оцениваться. Это называется «оценкой короткого замыкания».

В случае логического И (&&) и логического ИЛИ (||) второе выражение не будет оцениваться, если первого выражения достаточно для определения значения всего выражение.

В случае, описанном выше:

if(A == 1 || B == 2) {...}

... второе выражение не будет оцениваться, потому что

TRUE || ANYTHING всегда оценивается как TRUE .

Аналогично,

FALSE && ANYTHING , всегда оценивается как FALSE , так что это условие также вызовет оценка короткого замыкания .

Пара замечаний

  • Оценка короткого замыкания не будет применяться к перегрузке && и || ].
  • В C ++ вам гарантируется , что первое выражение будет вычислено первым. Некоторые языки не гарантируют порядок оценки, а VB вообще не выполняет оценку короткого замыкания. Это важно знать, переносите ли вы код.
17
ответ дан 3 December 2019 в 13:47
поделиться

Часть B == 2 не оценивается.

Будьте осторожны! Не помещайте туда что-то вроде ++ B == 2!

1
ответ дан 3 December 2019 в 13:47
поделиться

C ++ применяет сокращение к вычислению логического выражения, поэтому B == 2 никогда не вычисляется, и компилятор может даже полностью его опустить.

1
ответ дан 3 December 2019 в 13:47
поделиться

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

if(A == 1 || B == 2){...}

, скомпилированный в псевдоассемблер, может быть:

    load variable A
    compare to constant 1
    if equal, jump to L1
    load variable B
    compare to constant 2
    if not equal, jump to L2
L1:
    ... (complete body of if statement)
L2:
    (code after if block goes here)
1
ответ дан 3 December 2019 в 13:47
поделиться

Это оценка короткого замыкания , как говорит Джеймс. Ленивое вычисление - это совсем другое.

1
ответ дан 3 December 2019 в 13:47
поделиться

B == 2 никогда не оценивается.

См. Оценка короткого замыкания для получения дополнительной информации.

0
ответ дан 3 December 2019 в 13:47
поделиться

Нет, это не так.

То же самое с && , если одно неверно, другое не беспокоит.

0
ответ дан 3 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: