В следующем минимальном примере S::foo
работает, но S::bar
не работает.Почему аргумент аргумента Variadic шаблона не работает для этого указателя функции?
Единственным отличием является порядок пакетов параметров Ts
и Us
.
struct FPtr
и S::lol
- лучшее обходное решение, которое я нашел, но на практике это довольно неудобно.
Почему вычисел аргумента для bar
сбой (тем более, что я явно указал типы, поэтому никакого вычета не должно происходить вообще)? Является ли это ошибкой компилятора (встречается с clang++ 3.5
и g++ 4.9
), или это по стандарту, почему-то?
template<typename ... Ts>
struct FPtr {
FPtr(void (*val)(Ts ...)) : val{val} {}
void (*val)(Ts ...);
};
template<typename ... Ts>
struct S {
template<typename ... Us>
void lol(FPtr<Us ..., Ts ...>) {}
template<typename ... Us>
void foo(void (*)(Ts ..., Us ...)) {}
template<typename ... Us>
void bar(void (*)(Us ..., Ts ...)) {}
};
void f(int, float) {}
void g(float, int) {}
int main() {
S<int> s;
s.lol<float>(FPtr<float, int>(g));
s.foo<float>(f);
s.bar<float>(g);
}
Сообщение об ошибке:
$ clang++ -std=c++14 t27.cpp -Wall -Wextra -pedantic
t27.cpp:31:4: error: no matching member function for call to 'bar'
s.bar<float>(g);
~~^~~~~~~~~~
t27.cpp:18:7: note: candidate template ignored: failed template argument deduction
void bar(void (*)(Us ..., Ts ...)) {}
^
Примечание: Я сообщил об этой ошибке на трекерах ошибка GCC и LLVM.
Возможно, g ++ 5.1 исправить эту проблему. –
Пример может быть упрощен до [this] (http://coliru.stacked-crooked.com/a/3cf49423a0d67d49). – Jarod42
@ Jarod42 это ведет себя по-другому; он _does_ компилируется в обоих компиляторах, когда не полагается на автоматическую дедукцию. –