Поиск имен для имен, не зависящих от параметра шаблона в VC ++ 2008 Express. Это ошибка? - PullRequest
5 голосов
/ 05 мая 2010

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

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

template <typename T> 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 Express вызывается функция bar(int).Это было бы поведение, я ожидаю, если bar(3); в теле шаблона зависит от параметра шаблона.Но это не так.Правило, которое я обнаружил здесь , гласит: «Стандарт C ++ предписывает, что все имена, которые не зависят от параметров шаблона, привязываются к их текущим определениям при разборе функции или класса шаблона».Я не прав, что «текущее определение» bar при разборе функции шаблона foo является определением void bar(double d);?Почему это не так, если я ошибаюсь.В этом модуле компиляции нет предварительных объявлений bar.

Ответы [ 2 ]

3 голосов
/ 05 мая 2010

Это действительно ошибка в компиляторе. Известно, что проблема существовала в 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 неправильно реализует двухфазный поиск.

2 голосов
/ 05 мая 2010

АндрейТ правильно.Фактически, ваш код практически идентичен примеру из стандарта (§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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...