#c #template-specialization
#c #шаблон-специализация
Вопрос:
там:
Каков результат следующих кодов?
foo.h
#include <iostream>
template<class _Tp>
struct Foo
{
void print() { std::cout << "foon"; }
};
foo.cxx
#include "foo.h"
template<>
void Foo<int>::print()
{
std::cout << "foo<int>n";
}
main.cxx
#include "foo.h"
int main()
{
Foo<double>().print();
Foo<int>().print();
return 0;
}
Результаты разные:
-
при соблюдении MSVC,
foo foo
-
при компиляции с помощью g ,
foo foo<int>
Я хотел бы получить второй результат независимо от компиляторов. Что я должен сделать дополнительно для достижения? Если возможно, не могли бы вы дать мне объяснение базовых стандартов или механизма. Спасибо!
Комментарии:
1. «Результат следующих кодов» является ошибкой компиляции в foo.cxx, поскольку он не содержит допустимого кода C .
2. Я изменил неправильно введенный: void Foo<int>::void print() —> void Foo<int>::print() Не могли бы вы увидеть еще раз, спасибо.
3. Вам просто нужно объявить специализацию в заголовочном файле, чтобы она была видна во всех единицах перевода. Добавьте
template<> void Foo<int>::print();
объявление в файл заголовка.
Ответ №1:
Ваша программа имеет неопределенное поведение.
Существует две реализации Foo<int>::print()
: встроенное определение, полученное из определения шаблона класса, и нестрочное определение в foo.cxx. Компилятор волен выбирать либо.
Компилятор не требуется для диагностики этого как проблемы. Многие из них (по-видимому, включая g и MSVC) выбирают этот маршрут для определения шаблонов классов и их функций-членов.
Чтобы убедиться, что оба компилятора выбирают реализацию в foo.cxx, объявите функцию в foo.h .
#include <iostream>
template<class _Tp>
struct Foo
{
void print() { std::cout << "foon"; }
};
template<> void Foo<int>::print();
Комментарии:
1. Спасибо, но есть ошибки ссылки: неразрешенные внешние символы в MSVC, где, как это нормально в g .
2. @DongikShin, моя первая реакция заключается в том, что, возможно, foo.cxx не является частью сборки. Если foo.cxx является частью сборки, я не могу объяснить ошибку компоновщика.
Ответ №2:
Это интересно. Я знаю, что шаблоны интерпретируются во время компиляции, а не во время компоновки. Итак, на мой взгляд, шаблон специализации должен реализовываться в каждом cpp-файле. Какая у вас версия g ?
Ответ №3:
Если foo.h выглядит следующим образом, оба компилятора выдают одинаковые результаты. Но я не знаю почему.
#include <iostream>
template<class _Tp>
struct Foo
{
void print();
};
template<class _Tp>
void Foo<_Tp>::print()
{
std::cout << "foon";
}
template<> void Foo<int>::print();