Неиспользуемый идентификатор, используемый в качестве аргумента по умолчанию в шаблоне без инстанцирования

Сегодня я нашел фрагмент кода, эквивалентный следующему:

enum X
{
    x1 = 0,
    x2 = 1
};

template<typename T>
void bar(T obj, X x = x3) { }
//                    ^^
//                    This identifier is bogus!

int main() { }

Оба VC10 и VC12 счастливо скомпилируют его. Оба clang 3.4 и GCC 4.8.1 отклоняют его (что я и ожидал).

Является ли это ошибкой, или поведение VC действительно разрешено Стандартом? Если да, то какие соответствующие пункты?

Ответы

Ответ 1

Хорошо известно, что VC не имеет двухфазного поиска. Это означает, что он принимает всевозможные bogosity в шаблонах, если он по крайней мере выглядит как синтаксически допустимый С++, и он фактически не создается.

Это еще один из этих экземпляров.

Как вы видите в их дорожной карте соответствия, двухфазный поиск запланирован на некоторое время после пост-RTM CTP, который, как я полагаю, означает, что у вас будет доступ к нему после оплаты следующей итерации пакета Visual Studio.

Что касается стандартных ссылок, 14.6/9-10 говорят:

При поиске декларации имени, используемого в определении шаблона, обычные правила поиска (3.4.1, 3.4.2) используются для не зависимых имен. [...]

Если имя не зависит от параметра шаблона (как определено в 14.6.2), объявление (или набор деклараций) для этого имени должно быть в области видимости в точке, где имя отображается в определении шаблона.