2016-11-20 7 views
3

Рассмотрим следующий пример: минимальныйВыделение и пакет параметров, который не является последним параметром шаблона: этот допустимый код?

template<typename... A, typename R> 
void f(A&&..., R(*)(A...)) {} 

void g(int, char) {} 

int main() { 
    f<int, char>(42, 'c', g); 
} 

Параметр пакета A не является последним параметром.
В любом случае, я думал, что R может быть выведен из указателя функции из-за [temp.param]/11.

GCC (6,2) agrees with me об этом, в то время как звон (3,9) rejects the code и говорит, что он не может вывести аргумент шаблона R.

Было ли мое ожидание неправильным, поэтому GCC не должен его принимать или является проблемой clang?

+0

Что происходит, когда прототипом является 'R (*) (A ...), A && ...'? Я думаю, что «clang» прав, потому что пакет аргументов должен проглотить указатель на функцию, следовательно, не выводить «R». – StoryTeller

+0

@StoryTeller Хорошая точка. Оба компилятора принимают код. Во всяком случае, это не совсем то же самое. Перемещение указателя функции также позволяет удалить '' и вызвать 'f' как' f (g, 42, 'c') '. – skypjack

+0

Я не уверен, что это * проблема. Возможно, только расширение GCC. – StoryTeller

ответ

1

С этого упомянутого пункта:

Если шаблон-параметр шаблона класса, переменной шаблона или шаблона псевдонима имеет шаблонный аргумент по умолчанию, каждый последующий шаблон-параметр должен либо иметь template- по умолчанию аргумент предоставлен или является пакетом параметров шаблона. Если шаблон-шаблон шаблона первичного класса, шаблон первичной переменной или шаблон псевдонима является пакетом параметров шаблона, он должен быть последним параметром шаблона. Пакет параметров шаблона функции не должен сопровождаться другим параметром шаблона , если только этот параметр шаблона не может быть выведен из списка параметров-типа ([dcl.fct]) шаблона функции или имеет аргумент по умолчанию ([temp.deduct]). Параметр шаблона шаблона руководства дедукции ([temp.deduct.guide]), который не имеет аргумента по умолчанию, должен выводиться из списка типов параметров шаблона руководства по вычитанию. [Пример:

template<class T1 = int, class T2> class B; // error 

// U can be neither deduced from the parameter-type-list nor specified 
template<class... T, class... U> void f() { } // error 
template<class... T, class U> void g() { } // error 

- конец пример]

В этом случае template<typename... A, typename R> не может быть выведена из параметров для типа списка шаблона функции, потому что с:

void f(A&&..., R(*)(A...)) 

A&&... является жадным, и он будет потреблять g как A&& не R(*)(A...)

Говоря педантично, как в temp.deduct.call-1:

Для параметра функции пакета, что происходит в конце параметр декларирования-лист, удержание выполняется для каждого оставшегося аргумента вызова, принимая тип Р declarator-id пакета параметров функции как соответствующий тип параметра шаблона функции. Каждый вывод выводит аргументы шаблона для последующих позиций в пакетах шаблонов параметров, расширенных пакетом параметров функции. Когда пакет параметров функций появляется в невыводимом контексте ([temp.deduct.type]), тип этого пакета параметров не выводится.

как и в temp.deduct.type#9:

Если P имеет форму, которая содержит < T> или < я>, то каждый аргумент Pi соответствующего шаблона списка аргументов Р сравнивается с соответствующим аргумент Ai соответствующего списка аргументов шаблона A. Если список аргументов шаблона из P содержит расширение пакета, которое не является последним аргументом шаблона, весь список аргументов шаблона является невыводимым контекстом. Если Pi является пакет расширения, то модель Pi сравнивается с каждым оставшимся аргументом в списке аргументов шаблона А.

И это не может быть определено, как вы можете увидеть в третьем примере.

clang is right when reject it.

+1

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

+0

'14.8.2.5 Выделение аргументов шаблона из типа [temp.deduct.type]' является частью '14.8 Специализация шаблонов функций [temp.fct.spec]' – Danh

+0

Во всяком случае, я добавил некоторый текст из [temp.deduct.call] – Danh

 Смежные вопросы

  • Нет связанных вопросов^_^