2015-07-13 40 views
5

W N4296 3,2 [basic.def.odr] P3:Jedna z definicji zasada o ekspresji dostępu członka klasy

zmienna x którego nazwa pojawia się jako potencjalnie z wyrażenia ex jest ODR wykorzystywane przez ex chyba zastosowanie konwersji wartości do rvalue na x daje stałą ekspresję, która nie wywołuje żadnych nietrywialnych funkcji, a jeśli x jest obiektem, ex jest elementem zestawu potencjalnych wyników wyrażenia e, gdzie albo lwartości -to-rvalue jest stosowane do e, lub e jest odrzuceniem ed-value expression.

Jak wyjaśnić ten akapit? Znalazłem dwa wyjaśnienia.

1 stąd rozłamu "Trying to understand [basic.def.odr]/2 in C++14 (N4140)"

Zróbmy to na etapy: Występowanie zmiennej `x` w wyrażeniu` ex` stanowiącym ODR wykorzystania, chyba że:
  1. Każda zeex nie jest potencjalnie oceniane lub
  2. Wszystkie poniższe muszą być spełnione:
    1. „nakładanie konwersję lwartość-to-RValue do x daje stały wyrażenia nie odwołuje się żadnych nieoczywiste funkcji”i
    2. "ex jest elementem zestawu potencjalnych wynikami wyrażenie ei jedną z następujących czynności posiada:
      1. albo konwersja lwartość do RValue nakłada się e "
      2. "lube jest wyrażeniem odrzucono wartość"

i 2 z cppreference http://en.cppreference.com/w/cpp/language/definition

variab le x w potencjalnie z wyrażenia ex jest ODR wykorzystywane chyba każdy z następujących warunków:

  • stosowania lwartość-to-RValue konwersji x daje stały wyrażenia nie odwołuje nie- trywialne funkcje

  • x przedmiotem i ex jest jednym z możliwych wyników większej ekspresji e, jeżeli większa ekspresyjny albo ekspresja odrzucono wartość lub konwersji lwartość do RValue

Pierwsza odpowiedź o dwóch zasad jest i, z drugiej jest dowolny. Który jest poprawny?

Proszę podzielić zasady na etapy, aby wyjaśnić ten kod:

struct S { static const int x = 0; }; 
extern S s;// no definition of s 
int i = s.x;// is s odr-used? is x odr-used? 
      // gcc 5.1.0 is ok 

Odpowiedz

3

cppreference jest mylił; z języka w standardzie (niezależnie od wersji) jasno wynika, że ​​oba podrozdziały muszą zawierać. Poprawiłem to.

W twoim przykładzie s nie jest wyrażeniem stałym (C++ 14: nie spełnia wymagań dla pojawiania się w wyrażeniu stałym), więc jest odr-używane. Drugi podrozdział nie powstaje.

Tymczasem x jest ODR wykorzystywane, ponieważ chociaż byłoby możliwe użycie x w stałej ekspresji w odpowiednim kontekście (na przykład jako tablica wiązaniu w definicji S); x nie jest jednym z potencjalnych wyników otaczającego wyrażenia s.x, które jest jedynym zamykającym wyrażeniem podlegającym transformacji wartości wyrzuconej lub konwersji l-wartości do r-wartości.

gcc może być OK bez definicji s lub x, ale nie ma wymogu, aby implementacja zdiagnozowała każde naruszenie odr.

+2

_ Zmienna jest wprowadzana przez deklarację odniesienia inną niż niestatyczny element danych lub ** obiektu ** _. 'x' jest obiektem, więc jest zmienną. – stackcpp

+0

@stackcpp masz rację. Naprawię moją odpowiedź. – ecatmur

+0

@dyp przepraszam, musi być zły dzień. Oczywiście jest to obiekt kontra referencja, a nie obiekt typu klasowego w stosunku do pierwotnego. – ecatmur