Что выдаст код — 1 или 2?
Зависит от настроек линковки!
$ g++ a.cpp b.cpp -o a -fuse-ld=lld && ./aПочему так получается? Все просто: символы, полученные при явной специализации, являются сильными, а при отсутствии явной специализации — слабыми. В первом случае получается так, что слабый символ перекрывается сильным, и мы получаем
2
$ g++ -Wl,--start-lib a.cpp b.cpp -Wl,--end-lib -o a -fuse-ld=lld && ./a
1
2. Во втором случае (с --start-lib) сильный символ не используется, поскольку линкер видит, что у нас уже есть слабый символ, и игнорирует содержимое a.o, который был получен из a.cpp. Но тогда мы получаем 1.(Если кто-то не понял объяснение выше, то советую для начала прочитать замечательный пост про линковку, а потом перечитать абзац выше еще раз. Если все равно непонятно, просите помощи в комментах.)
А вообще, судя по StackOverflow, программа попросту некорректна. Цитируя Стандарт C++,
> If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.