Это одна из частей стандарта, которая изменилась с C++ 03 на C++ 11.
В C++ 03, [temp.arg.nontype] гласит:
Шаблон-аргумент для не-типа, не-шаблон Шаблон-параметр должен быть одним из:
- [...]
- [...]
- адреса объекта или функции с внешним связыванием, в том числе шаблонов функций и функциональных шаблоны идентификаторов, но за исключением членов нестатического класса, выраженным как & Ид выражения, где & не является обязательным, если название относится к функции или массива, или если соответствующий шаблон-параметр является ссылкой; или
- [...]
В C++ 11, которые получили обновленные в результате issue 1155, хотя GCC до сих пор a bug в отношении такого поведения:
- постоянное выражение (5.19), которое обозначает адрес полного объекта со статическим временем хранения и внешним или внутренним соединением или функцией с внешняя или внутренняя связь , включая функцию шаблоны и функции-шаблоны функций, но исключая нестатические члены класса, выраженные (игнорируя круглые скобки) как & id-expression, где id-выражение - это имя объекта или функции, за исключением того, что & может опускаться, если имя относится к функции или массиву и должно быть опущено, если соответствующий шаблон шаблона является ссылкой; или
В C++ 14, которые получили упрощена еще дальше и даже не упоминает о связи.
Что касается вашего конкретного вопроса, спецификатор extern
добавляет внешнюю связь к baz_instance
. Без него baz_instance
имеет внутреннюю связь. В C++ 03 вам понадобилась внешняя связь, чтобы иметь тип шаблона типа non-type ссылочного типа. В C++ 11 вас больше нет - поэтому extern
больше не нужен, и он компилируется без него.
Как вы можете видеть из исходного кода, база не была определена в другом исходном файле. Кроме того, он не объяснил бы, почему экземпляр структуры можно передать шаблону с внешним, но не может без внешнего. – smoes
См. Редактирование в моем ответе –