Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
1402 / 644 / 135
Регистрация: 11.08.2011
Сообщений: 2,299
Записей в блоге: 2
1

Почему компилируется не объявленная переменная в шаблоне?

07.01.2014, 15:41. Просмотров 872. Ответов 6
Метки нет (Все метки)


Нашел на просторах интернета такой код
C++
1
2
3
4
5
6
7
8
9
10
template<typename T>
    T foo(int x, T ololo)
    {
        a = 5;
    }
 
int main()
{
 
}
И этот код скомпилился в студии 12. Почему он компилится?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.01.2014, 15:41
Ответы с готовыми решениями:

Почему переменная объявленная static работает не корректно?
Переменная j=25 я её обозначил как static int j; и присвоил число 25. Значит эта переменная должна...

Статическая переменная в шаблоне
// // (---.Array_hpp---) // #ifndef Array_HPP // Preprocessor gates...

Почему возможно задать массив с размером -1 (почему такое вообще компилируется)?
Всем привет. Долгое время не писал на плюсах, решил пройтись по основам, вспомнить. По...

Не видна переменная, объявленная в Form1
Здравствуйте. Есть Form1 и класс Objects: public partial class Form1 : Form { ...

6
3239 / 2047 / 350
Регистрация: 24.11.2012
Сообщений: 4,897
07.01.2014, 15:48 2
Это только шаблон, инстанса не создается.
g++ благополучно ругнулся: error: ‘a’ was not declared in this scope
2
14034 / 7517 / 1779
Регистрация: 30.01.2014
Сообщений: 12,570
29.11.2014, 19:57 3
Некропост, но ответа на вопрос так и не было

Цитата Сообщение от Dani Посмотреть сообщение
Почему он компилится?
Из-за отсутствия two-phase name lookup в студии. Из-за этого можно писать любую фигню в шаблонах, пока он не инстанцирован. Эта вольность допущена для ускорения компиляции.
3
Эксперт С++
8403 / 3940 / 862
Регистрация: 15.11.2014
Сообщений: 8,888
30.11.2014, 23:32 4
msvc
http://rextester.com/UNBNR47669

gcc
http://ideone.com/2E6IZ
2
1453 / 790 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
31.12.2014, 13:06 5
Я не понял прикола - почему gcc выводит oh lol
0
Эксперт С++
1919 / 1261 / 360
Регистрация: 16.05.2013
Сообщений: 3,293
Записей в блоге: 6
31.12.2014, 13:18 6
Цитата Сообщение от DiffEreD Посмотреть сообщение
Я не понял прикола - почему gcc выводит oh lol
Так глобальная переменная, а mvalue не определена в классе CMyAwesomeClass. Этот код ставит все точки над "ы":
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;
string mvalue="ok";
template<class HAHAHA>
class Trololo {
public:
    Trololo():
        mvalue("oh lol")
    {}
    string mvalue;
};
template<class DISREGARD_THAT>
class CMyAwesomeClass: public Trololo<DISREGARD_THAT> {
public:
    string mvalue;
    void SetValue(string value)  {
        mvalue = value;
    }
};
int main() {
    CMyAwesomeClass<int> c;
    c.SetValue("ok");
    cout<<c.mvalue<<endl;
    return 0;
 
}
А стандарт по этому поводу говорит следущее:
1
Миниатюры
Почему компилируется не объявленная переменная в шаблоне?  
Эксперт С++
8403 / 3940 / 862
Регистрация: 15.11.2014
Сообщений: 8,888
31.12.2014, 17:38 7
Цитата Сообщение от DiffEreD Посмотреть сообщение
Я не понял прикола - почему gcc выводит oh lol
two-phase name lookup жеж.

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

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

Ну так вот, при первом проходе, поскольку он ещё не инстанцировал шаблон целиком,
то он не знает в точности всего его строения.

Грубо говоря, компилятор не знает о том, что где-то в базовом классе есть член с таким же именем, и ничто ему на это не указывает.


Смотрите:

http://ideone.com/OOnYRU

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
 
using namespace std;
 
string mvalue="ok";
 
template<class HAHAHA>
class Trololo
{
public:
    Trololo(void):
        mvalue("oh lol")
    {}
    string mvalue;
};
 
template<class DISREGARD_THAT>
class CMyAwesomeClass: public Trololo<DISREGARD_THAT>
{
public:
    void SetValue(string value)
    {
        this->mvalue = value; // <--- смотрим сюда
    }
};
 
int main() {
    CMyAwesomeClass<int> c;
    c.SetValue("ok");
    cout<<c.mvalue<<endl;
    return 0;
}
Теперь поведение стало ожидаемым. Я лишь добавил ключевое слово this.

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

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

Резюмируя:
Поскольку cl (компиляторы вижал студии) такие вещи пропускает,
и все вроде бы работает, как нужно,
то очень часто программисты забывают о нюансах.

И в результате код оказывается непереносимым, или хуже того - работает но с сюрпризами.

Поэтому, используйте this, если пишите шаблоны.
Это - единственная 100% гарантия от подобных ошибок.
5
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.12.2014, 17:38

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Переменная объявленная на другой форме
Доброго времени суток, Господа. Начинаю работать с C# Программа должна открывать ком-порт на...

Не видна переменная, объявленная в main
Пишет, что переменная numOne не объявлена, хотя я ее объявил в main. #include &lt;stdio.h&gt; void...

Переменная, объявленная в блоке Try - Catch видна не для всего метода
class Program { static void Main() { BinaryWriter dataOut; ...

Переменная, объявленная в цикле "не существует в текущем контексте"
Подскажите не могу разобраться,как вывести переменную ай для дальнейшего поиска. using System;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.