со следующим минимальным примером я получаю ошибку компоновщика в моей локальной системе в Visual Studio 15.8.7 (стандартное консольное приложение со стандартными настройками (только что удалены предварительно скомпилированные заголовки)): «Ошибка LNK1179 неверный или поврежденный файл: дубликат COMDAT '?? $ f @ H @@ YAXH @ Z '"
#include <cstdio>
template<typename T> void f(T) { printf("1"); } //#1. T can be deduced
template<typename T> void f(int) { printf("2"); } // #2. T needs to be specified explicitly
int main()
{
f(8); // a) calls #1
f<int>(8); // b) calls #2
}
- Комментирование вызова a) или вызова b) приведет к успешному соединению.Автономный вызов а) вызывает шаблон определения # 1.Второй вызов б) вызывает определение шаблона №2.Как и ожидалось.
- Построение в режиме выпуска завершено успешно.Выходное значение равно 11. Таким образом, оба вызова вызывают определение шаблона № 1.Неожиданный. ODR-нарушение?
- Кроме того, я заметил следующее странное поведение (в настройках отладки):
- я закомментирую определение шаблона # 2
- я делаюполная перестройка
- я комментирую в определении шаблона # 2
- я собираю (не перестраиваю, просто собираю)
- сборка завершается
- вместо этого выводится 11из 12
Инкрементное связывание, делающее странные вещи?
На wandbox, godbolt и coliru я могу скомпилировать, связать, запустить и получитьожидаемое поведение с gcc и clang.
Наблюдения, описанные в пуле 3, заставили меня подумать, что это связано с добавочной связью.Но, может быть, код тоже не очень хорошо определен?При изучении https://en.cppreference.com/w/cpp/language/function_template я обнаружил следующее:
Два выражения, включающие параметры шаблона, называются функционально эквивалентными, если они не эквивалентны, но для любого заданного набора аргументов шаблона выполняется оценкадва выражения приводят к одному и тому же значению.
и
Если программа содержит объявления шаблонов функций, которые функционально эквивалентны, но не эквивалентны, программа является некорректной;Диагностика не требуется.
Итак, код выше не сформирован?Есть ли у меня нарушение ODR?Или все нормально, и это просто ошибка компоновщика / компилятора?
edit: фиксированная точка 3. Я комментирую в определении # 2 или курсе.
Обновление: Новоедень, проблемы решены, я думаю.Сегодня я не могу воспроизвести проблему.Я ничего не изменил в моей системе.Я только загрузился, открыл свой проект, и он работал как ожидалось.Не знаю, что происходит.Но так лучше по сравнению с изучением новых специальных правил перегрузки тайных шаблонов: -P