Поиск имени для имен, не зависящих от шаблонного параметра в VC ++ Экспресс 2008 года. Действительно ли это - ошибка?

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

void bar(double d)
{
    std::cout << "bar(double) function called" << std::endl;
}

template  void foo(T t)
{
    bar(3);
}

void bar(int i)
{
    std::cout << "bar(int) function called" << std::endl;
}

int main()
{
    foo(3);
    return 0;
}

Когда я компилирую этот код в VC ++ Экспресс 2008 года, функция bar(int) назван. Это было бы поведением, я буду ожидать если bar(3);в шаблоне тело зависело от шаблонного параметра. Но это не. В правиле, которое я нашел здесь, говорится, что "Стандарт C++ предписывает, чтобы все имена, которые не зависят от шаблонных параметров, были связаны со своими существующими определениями при парсинге шаблонной функции или класса". Я неправильно, то "существующее определение" bar при парсинге шаблонной функции foo определение void bar(double d);? Почему это не имеет место, если я неправ. Нет никаких предописаний bar в этой единице компиляции.

5
задан Maciej Hehl 5 May 2010 в 17:04
поделиться

2 ответа

Это действительно ошибка компилятора. Было известно, что проблема существует в VS2005 и ранее (я использую блог Blogspot в качестве записной книжки для подобных случаев, см. 1.3 здесь ). Судя по всему, он присутствует и в VS2008.

Вы можете протестировать его с помощью следующего простого кода

int bar(double d) { return 0; }

template <typename T> void foo(T t) {
  int i = bar(3);
}

void bar(int i);

int main() {
  foo(3);
}

Этот код хорошо сформирован (вы можете скомпилировать его с помощью компилятора Comeau Online), но я уверен, что VS подавится им, потому что VS неправильно реализует двухэтапный поиск в этом случае.

3
ответ дан 14 December 2019 в 19:06
поделиться

AndreyT прав. На самом деле, ваш код практически идентичен примеру из стандарта (§14.6.3/1):

void g(double);
void h();

template<class T> class Z {
public:
    void f() {
        g(1);    //calls g(double)
        h++;     //ill-formed: cannot increment function;
                 // this could be diagnosed either here or
                 // at the point of instantiation
    }
};

void g(int);     // not in scope at the point of the template
                 // definition, not considered for the call g(1)
2
ответ дан 14 December 2019 в 19:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: