2015-07-04 2 views
15

У меня есть функция foo, которая принимает указатель на переменную функцию как свой аргумент.pre-typedef'ing аргумент переменной-функции-указателя

Я хотел бы использовать «using» для определения типа аргумента до объявления функции.

template <typename ... vARGS> 
using TFuncType = void(*)(vARGS ... V_args); 

template <typename ... vARGS> 
void foo(TFuncType<vARGS ...> funcptr) {} 

void bar(int i) {} 

int main() { 
    foo(&bar); // This line fails to compile. 
} 

Это не скомпилировано. Ошибка (через clang с использованием C++ 1z):

/make/proj/test/variadic-funcparam-deduce2.cpp:39:5: error: no matching function for call to 'foo' 
foo(&bar); 
^~~ 
/make/proj/test/variadic-funcparam-deduce2.cpp:33:36: note: candidate template ignored: substitution failure [with vARGS = int] 
template <typename ... vARGS> void foo(TFuncType<vARGS ...> funcptr) {} 

Почему ошибка «int» не работает?

Я могу успешно компилируется, если я явно писать тип внутри Foo():

template <typename ... vARGS> 
void foo(void(*funcptr)(vARGS ... V_args)) {} 

Но я не могу получить начальное («использование») версия для работы даже при явном указании параметров шаблона, а также с использованием предварительно отливают TFuncType<int> для аргумента, то есть:

int main() { 
    TF_call<int> fptr = &bar; // This line is OK. 
    foo<int>(fptr); 
} 

кто-нибудь знает, что это здесь?

Есть ли что-то странное в использовании переменных и/или указателей функций typedef'd ("using"), которые мне не хватает?

+5

Работает с GCC, и я не могу думать ни о каком правиле, этот код ломается, поэтому я собираюсь пойти с ошибкой Clang. –

+0

Хорошо, я оставлю его на час или около того, а затем напишу отчет об ошибке, если не будет комментариев. Благодарю. – xaxazak

+0

Версия компилятора? – Yakk

ответ

1

Я считаю, что это может быть связано со следующим текстом, который я скопировал из this answer, что сам принимает от стандарта C++ в 14.5.7 [temp.alias] пункт 2:

Когда шаблон-идентификатор относится к специализации шаблона псевдонима, эквивалентно ассоциированному типу, полученному путем подстановки его шаблонных аргументов для параметров шаблона в идентификаторе типа шаблона псевдонимов. [Примечание: имя шаблона псевдонима никогда не выводится. - конца примечание]

Если я интерпретация этого права, то это означает, что GCC принимая код фактически несоответствующий.

+0

Да, теперь я уверен, что это незаконно. Спасибо, ваш фрагмент объясняет. – xaxazak

+0

Я не уверен. Он говорит, что шаблон псевдонима * имя * никогда не выводится. Это не выводит имя, потому что имя уже указано в объявлении функции шаблона. Этот оговорка, похоже, применяется только в том случае, если ваш шаблон ожидает параметр _template template_. См. [Пример cppreference] (http://en.cppreference.com/w/cpp/language/template_argument_deduction#Alias_templates) –