Что является формальным в C++ const reference (не ссылка на const, а ссылка на const)

Дано

template< class Type >
void constref( Type const ) {}

void constref_call() { double x; constref<double&>( x ); }      // OK

template< class Type >
using reference = Type&;

void foo( reference< const int > const x ) { (void) x; }        // OK

template< class Type >
void foot( reference< const Type > arg ) { (void) arg; }

void foot_call() { foot( 3.14 ); }      // Deduces arg type no problem.

void foo2( int const& const x ) { (void) x; }                   // !

В Visual C++ и g++ этот код компилируется, как указано в комментариях, только с foo2 провоцируя ошибку компиляции.

Мне бы хотелось foo аналогичным образом приведет к ошибке компиляции, чтобы иметь возможность использовать эту нотацию с теми же ограничениями, что и нотация оператора "неудачного эксперимента" основного языка.

Я подозреваю, что причина того, что foo компилируется так же, как причина, почему вызов в constref_call компилирует, какое-то исключение для шаблонов, но так ли это на самом деле - каковы здесь формальные правила стандарта?

1 ответ

Решение

Цитирую C++ 11, 8.3.2 / 1:

... Cv-квалифицированные ссылки некорректны, за исключением случаев, когда cv-квалификаторы вводятся с помощью typedef (7.1.3) или аргумента типа шаблона (14.3), и в этом случае cv-квалификаторы игнорируются....

Другие вопросы по тегам