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

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

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Стандарт. Раздел 2. Перевести абзац на русский язык http://www.cyberforum.ru/cpp-beginners/thread1064912.html
Есть проблема с переводом этого абзаца стандарта С++: Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines. Only the last backslash on any physical source line shall be eligible for being part of such a splice. If, as a result, a character sequence that matches the syntax of a...
C++ Случайных чисел в диапазоне! Я из Болгарий,случайно нашел ето классньй сайт.Я только любитель невероятного язьйка С++.Пишу с ошибки по руском и для ето извиняюсь.Вот у меня вопрос(задача) для всех ответ спосибо заранее. Задача: Написать прототип функции: double average(int t,int p,int q); генерирующие n случайных чисел в диапазоне ,p<q. На вход из клавиатуре-случайных чисел n и диапазон p,q. Функция должна... http://www.cyberforum.ru/cpp-beginners/thread1064908.html
Реш ить задачу с помо щью алгоритма перебора с возвратом C++
Перебрать все пути в графе между двумя заданными вершинами, не содержащие одинаковых вершин. ПОМОГИТЕ ПЖЛСТ)
C++ Обучение по книге Страуструпа "принципы и практика C++". Не выводится "Hello, World"
Ребят, помогите пожалуйста, пропал на первом же примере из книги, автор даёт код для вывода Hello world!#include "std_lib_facilities.h" int main() { cout << "hello, world!\n"; //вывод "Hello world!" return 0; } На сколько я понял, подключаемого в коде файла "std_lib_facilities.h" нет. Я его скачал, но куда его теперь скидывать и как вообще начать работать с visual studio т.е. как...
C++ В каком направлении следует развиваться программисту C++ http://www.cyberforum.ru/cpp-beginners/thread1064875.html
Сразу просьба не ругаться т.к. такие темы многих раздрожают)) Прочитал пару книг по С и С++, на работе пишу прошивки под микроконтроллеры, но хочется чего-то более серьёзного. Сейчас надо развиваться дальше в каком - либо направлении, выбор стоял либо читать электронику и уходить в ту сторону, пилить всякие ПЛИСины и паять всякие ужасы, либо развиваться в сторону разработки ПО и т.п.. Выбор пал...
C++ Найти сумму тех из элементов a2j(j=1,...,m), для которых a1j имеет значение наибольшего среди значений Даны натуральное число n, целочисленная матрица i=1,2; j=1,...,m. Найти сумму тех из элементов a2j(j=1,...,m), для которых a1j имеет значение наибольшего среди значений a11, a12,...,a1m. подробнее

Показать сообщение отдельно
hoggy
6369 / 2587 / 452
Регистрация: 15.11.2014
Сообщений: 5,722
Завершенные тесты: 1
31.12.2014, 17:38     Почему компилируется не объявленная переменная в шаблоне?
Цитата Сообщение от 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% гарантия от подобных ошибок.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru