При чтении этой части С ++ (14): a free draft N4141, closest to C++14Локальные правила класса выровнены с выводом типа с ++ 14?
9.8 деклараций локального класса [class.local]
[..] Имя локального класса является локальным для его ограждающих объем. [..]
Декларации в локальном классе не должны использовать odr-use (3.2) переменную с продолжительностью автоматического хранения из охватывающей области. [Пример:
//[..] void f() { static int s ; int x; // [..] struct local { int g() { return x; } // error: odr-use of automatic variable x int h() { return s; } // OK // [..] }; } local* p = 0; // error: local not in scope
-end пример]
Я заметил, что, во-первых - я могу определить p
с возвращаемого значения автоматического удержания:
auto f()
{
static int s;
int x;
struct local
{
int h() { return s; }
};
return local{};
}
decltype(f())* p = 0; // OK - ignored, that local is not in scope!
Может быть, это, кажется, хорошо, почему не использовать локальный тип, выведя его из возвращаемого значения функции, но - кажется, таким образом я могу получить доступ к локальной переменной s
до ее построения:
struct TalkativeInt
{
TalkativeInt() : value()
{
std::cout << "TalkativeInt()\n";
}
TalkativeInt(int value) : value(value)
{
std::cout << "TalkativeInt(" << value << ")\n";
}
int value;
};
auto f()
{
static TalkativeInt s = 7;
int x;
struct local
{
auto h() { return s.value; }
};
return local{};
}
decltype(f())* p = 0;
int main() {
decltype(f()) l;
std::cout << l.h();
}
Выход только ::
0
Но можно было бы ожидать:
TalkativeInt(7)
7
Оба лязг и НКУ не протестуют каким-либо образом, см demo.
Интересно, может быть, такой случай следует упомянуть как-то либо в
9.8 деклараций местного класса [class.local]
или в
7.1.6.4 авто спецификатором [dcl.spec.auto]
?
Конечно, я считаю, что чтение (и запись) из переменной перед ее построением плохой предмет, но я ничего не нашел об этом в стандарте - возможно, это было невозможно до C++ 14? Или есть некоторые основные правила, которые я просто забыл?
Ой, это противно. Это похоже на лазейку и, вероятно, вызывает неопределенное поведение ... – Quentin
Хмм. «Локальные объявления класса» говорят только о том, что имя не видно снаружи. Это не обязательно означает, что тип не может использоваться снаружи, как я его вижу. Я не совсем уверен, как вы могли бы использовать такую функцию pre-C++ 11, поскольку вы не могли даже объявить ее локальным. Но, возможно, я просто пропущу точку здесь. –
В §9.8 говорится только, что _name_ является локальным. Не совсем то, что вы можете использовать сущность без указания ее имени. – cpplearner