там:
Что является результатом следующих кодов?
foo.h
#include <iostream>
template<class _Tp>
struct Foo
{
void print() { std::cout << "foo\n"; }
};
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>
Я хотел бы получить второй результат независимо от компиляторов. Что я должен сделать дополнительно, чтобы достичь? Если возможно, дайте мне объяснение основных стандартов или механизма. Спасибо!
Ваша программа имеет неопределенное поведение.
Есть две реализации Foo<int>::print()
— встроенное определение, полученное из определения шаблона класса и не встроенного определения в foo.cxx. Компилятор свободен в выборе.
Компилятор не обязан диагностировать это как проблему. Многие из них (очевидно, включая g ++ и MSVC) выбирают этот маршрут для определений шаблонов классов и их функций-членов.
Чтобы убедиться, что оба компилятора выбирают реализацию в foo.cxx, объявите функцию в foo.h.
#include <iostream>
template<class _Tp>
struct Foo
{
void print() { std::cout << "foo\n"; }
};
template<> void Foo<int>::print();
Это интерес. Я знаю, что шаблоны интерпретируются во время компиляции, а не во время компоновки. Так что, на мой взгляд, шаблон специализации должен реализовываться у каждого файла cpp. Какая у вас версия g ++?
Если foo.h выглядит следующим образом, оба компилятора дают одинаковые результаты. Но я не знаю почему.
#include <iostream>template<class _Tp>
struct Foo
{
void print();
};
template<class _Tp>
void Foo<_Tp>::print()
{
std::cout << "foo\n";
}
template<> void Foo<int>::print();