Почему это ошибка для const-qualify пакета параметров указателей?

При реализации функции, которая принимает параметр обновление указателей на Ts..., почему я не могу const -qualify указатели, как это возможно с регулярными параметрами?

Я получаю ошибку несоответствующей подписи на последних GCC и Clang, и я не понимаю, почему, поскольку указатели const являются только деталью реализации (следовательно, это является законным для регулярных параметров).

template<typename... Ts>
class C
{
    void f(int*);
    void g(Ts*...);
};

template<typename... Ts>
void C<Ts...>::f(int* const) {} // Legal

template<typename... Ts>
void C<Ts...>::g(Ts* const...) {} // Compiler error

Я получаю эту ошибку:

prog.cc:12:16: error: out-of-line definition of 'g' does not match any declaration in 'C<Ts...>'
void C<Ts...>::g(Ts* const...) {}
               ^
1 error generated.

Вы также можете увидеть код и ошибки здесь.

Ответ 1

Я собираюсь записать его на пару ошибок компилятора (проверены Clang и GCC). Это смелое утверждение, я знаю, но [dcl.fct]/5 говорит, акцент мой:

Одно имя может использоваться для нескольких различных функций в одной области; это перегрузка функций. Все объявления для функции должны точно совпадать как с типом возврата, так и с типом-списком параметров. Тип функции определяется с использованием следующих правил. Тип каждого параметра (включая пакеты параметров функций) определяется из его собственного decl-specifier-seq и declarator. После определения типа каждого параметра любой параметр типа "массив T" или типа функции T настраивается как "указатель на T". После создания списка типов параметров, любые типы cv-квалификаторов верхнего уровня, изменяющие тип параметра, удаляются при формировании типа функции. Результирующий список преобразованных типов параметров и наличие или отсутствие эллипсиса или пакета параметров функции - это список параметров параметров. [Примечание. Это преобразование не влияет на типы параметров. Например, int() (const int p, decltype (p)) и int() (int, const int) являются идентичными типами. - конечная нота]

Который читает мне совершенно ясно, что объявления обоих участников (f и g) соответствуют определениям вне класса, что делает вашу программу действительной. Поэтому Clang и GCC должны его принять.