Информация об изменениях

Сообщение Re: Определение шаблона после использования от 03.04.2018 22:26

Изменено 03.04.2018 22:36 Constructor

Re: Определение шаблона после использования
Здравствуйте, andrey.desman, Вы писали:

AD>Почему этот код линкуется? Компилятор "собирает" запросы на инстанцирование?

AD>И должен ли по стандарту?

Де-юре этот код был не корректен до выхода C++11. См. Defect Report 993.

На данный момент место в стандарте, описывающее происходящее, выглядит так (см. главу Point of instantiation [temp.point], абзацы 1 и 8 в актуальной версии стандарта; выделение жирным мое):

1 For a function template specialization, a member function template specialization, or a specialization for a member function or static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization and the context from which it is referenced depends on a template parameter, the point of instantiation of the specialization is the point of instantiation of the enclosing specialization. Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.
...
8 A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation. A specialization for a class template has at most one point of instantiation within a translation unit. A specialization for any template may have points of instantiation in multiple translation units. If two different points of instantiation give a template specialization different meanings according to the one-definition rule (6.2), the program is ill-formed, no diagnostic required.


Т.е. имеем следующую картину:

#include <cstdio>

const char* name;

template<typename T>
void set_name(const char* n, T a);

void foo()
{
    set_name("test", 11);
}

// первая точка инстанцирования специализации set_name<int>
// (в соответствии с абзацем 1, она "follows the namespace scope declaration or definition that refers to the specialization")

template<typename T>
void set_name(const char* n, T a)
{
    name = n;
}

const char* get_name()
{
    return name;
}

int main(int argc, char* argv[])
{
    foo();
    printf("%s\n", get_name());
    return 0;
}

// вторая точка инстанцирования специализации set_name<int>
// (в соответствии с абзацем 8, "for any such specialization that has a point of instantiation within the translation unit,
// the end of the translation unit is also considered a point of instantiation")
Re: Определение шаблона после использования
Здравствуйте, andrey.desman, Вы писали:

AD>Почему этот код линкуется? Компилятор "собирает" запросы на инстанцирование?

AD>И должен ли по стандарту?

Де-юре этот код был некорректен до выхода C++11. См. Defect Report 993.

На данный момент место в стандарте, описывающее происходящее, выглядит так (см. главу Point of instantiation [temp.point], абзацы 1 и 8 в актуальной версии стандарта; выделение жирным мое):

1 For a function template specialization, a member function template specialization, or a specialization for a member function or static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization and the context from which it is referenced depends on a template parameter, the point of instantiation of the specialization is the point of instantiation of the enclosing specialization. Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.
...
8 A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation. A specialization for a class template has at most one point of instantiation within a translation unit. A specialization for any template may have points of instantiation in multiple translation units. If two different points of instantiation give a template specialization different meanings according to the one-definition rule (6.2), the program is ill-formed, no diagnostic required.


Т.е. имеем следующую картину:

#include <cstdio>

const char* name;

template<typename T>
void set_name(const char* n, T a);

void foo()
{
    set_name("test", 11);
}

// первая точка инстанцирования специализации set_name<int>
// (в соответствии с абзацем 1, она "follows the namespace scope declaration or definition that refers to the specialization")

template<typename T>
void set_name(const char* n, T a)
{
    name = n;
}

const char* get_name()
{
    return name;
}

int main(int argc, char* argv[])
{
    foo();
    printf("%s\n", get_name());
    return 0;
}

// вторая точка инстанцирования специализации set_name<int>
// (в соответствии с абзацем 8, "for any such specialization that has a point of instantiation within the translation unit,
// the end of the translation unit is also considered a point of instantiation")