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

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

Восстановить пароль Регистрация
 
Dani
1263 / 621 / 50
Регистрация: 11.08.2011
Сообщений: 2,236
Записей в блоге: 2
Завершенные тесты: 1
07.01.2014, 15:41     Почему компилируется не объявленная переменная в шаблоне? #1
Нашел на просторах интернета такой код
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. Почему он компилится?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.01.2014, 15:41     Почему компилируется не объявленная переменная в шаблоне?
Посмотрите здесь:

Статическая переменная в шаблоне C++
C++ Не компилируется почему-то
Не компилируется,не понимаю,почему C++
Почему не компилируется код C++
почему не компилируется программа ? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
07.01.2014, 15:48     Почему компилируется не объявленная переменная в шаблоне? #2
Это только шаблон, инстанса не создается.
g++ благополучно ругнулся: error: ‘a’ was not declared in this scope
DrOffset
6459 / 3833 / 885
Регистрация: 30.01.2014
Сообщений: 6,628
29.11.2014, 19:57     Почему компилируется не объявленная переменная в шаблоне? #3
Некропост, но ответа на вопрос так и не было

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

gcc
http://ideone.com/2E6IZ
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
31.12.2014, 13:06     Почему компилируется не объявленная переменная в шаблоне? #5
Я не понял прикола - почему gcc выводит oh lol
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 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;
 
}
А стандарт по этому поводу говорит следущее:
Миниатюры
Почему компилируется не объявленная переменная в шаблоне?  
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.12.2014, 17:38     Почему компилируется не объявленная переменная в шаблоне?
Еще ссылки по теме:

C++ почему не компилируется ?
C++ ааааааааааааааааа, почему не компилируется?
Почему не компилируется? C++

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

Или воспользуйтесь поиском по форуму:
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 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% гарантия от подобных ошибок.
Yandex
Объявления
31.12.2014, 17:38     Почему компилируется не объявленная переменная в шаблоне?
Ответ Создать тему
Опции темы

Текущее время: 16:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru