Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Dani
1393 / 637 / 57
Регистрация: 11.08.2011
Сообщений: 2,282
Записей в блоге: 2
Завершенные тесты: 1
#1

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

07.01.2014, 15:41. Просмотров 544. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.01.2014, 15:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Почему компилируется не объявленная переменная в шаблоне? (C++):

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

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

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

Почему не компилируется - C++
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; const double Pi = 3.14159; double Area(double...

Почему не компилируется? - C++
Привет, перейду сразу к делу. Вот все говорят, что Visual Studio самая крутая студия, а она даже не может скомпилировать эту простую...

почему не компилируется ? - C++
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;stdlib.h&gt; #include &lt;conio.h&gt; using namespace std; class element { ...

6
0x10
2474 / 1647 / 247
Регистрация: 24.11.2012
Сообщений: 4,068
07.01.2014, 15:48 #2
Это только шаблон, инстанса не создается.
g++ благополучно ругнулся: error: ‘a’ was not declared in this scope
2
DrOffset
7349 / 4449 / 1009
Регистрация: 30.01.2014
Сообщений: 7,292
29.11.2014, 19:57 #3
Некропост, но ответа на вопрос так и не было

Цитата Сообщение от Dani Посмотреть сообщение
Почему он компилится?
Из-за отсутствия two-phase name lookup в студии. Из-за этого можно писать любую фигню в шаблонах, пока он не инстанцирован. Эта вольность допущена для ускорения компиляции.
3
hoggy
6672 / 2856 / 491
Регистрация: 15.11.2014
Сообщений: 6,364
Завершенные тесты: 1
30.11.2014, 23:32 #4
msvc
http://rextester.com/UNBNR47669

gcc
http://ideone.com/2E6IZ
2
DiffEreD
1431 / 768 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
31.12.2014, 13:06 #5
Я не понял прикола - почему gcc выводит oh lol
0
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,117
Записей в блоге: 5
Завершенные тесты: 1
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
Миниатюры
Почему компилируется не объявленная переменная в шаблоне?  
hoggy
6672 / 2856 / 491
Регистрация: 15.11.2014
Сообщений: 6,364
Завершенные тесты: 1
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% гарантия от подобных ошибок.
4
31.12.2014, 17:38
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.12.2014, 17:38
Привет! Вот еще темы с ответами:

Почему не компилируется? - C++
Добрый день! Почему не компилируется данная программа. Хотелось бы чтобы из одного класса можно было вызвать метод другого класса. ...

Не компилируется почему-то - C++
Вот код программы, она вроде как бы работает, но все равно выдаются ошибки, помогите пожалуйста их исправить, в c++ я новичок: ...

Почему не компилируется с шаблонами? - C++
Точнее, компилируется, но не линкуется. Ошибка &quot;undefined reference&quot; в 9-й строке main.cpp. Никак не пойму, как же надо было написать? ...

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


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

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

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