3

В следующем минимальном примере 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.

+0

Возможно, g ++ 5.1 исправить эту проблему. –

+0

Пример может быть упрощен до [this] (http://coliru.stacked-crooked.com/a/3cf49423a0d67d49). – Jarod42

+0

@ Jarod42 это ведет себя по-другому; он _does_ компилируется в обоих компиляторах, когда не полагается на автоматическую дедукцию. –

ответ

3

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

, которая должна соответствовать вызову. У Clang и GCC были проблемы в таких областях, как это раньше, и их диагностика, как известно, была менее полезной. Удивительно, однако VC++ компилирует код.

Рассмотрите следующее, которое работает под обоими компиляторами.

template<class... Ts> 
struct S { 
    template<class... Us> 
    void bar(Us..., Ts...); 
}; 

int main() { 
    S<int>().bar<int>(1, 2); 
} 

Ваша программа имеет одинаковую семантику и должна обрабатываться одинаково.

+0

Как ваш код имеет ту же семантику, что и моя? Ваш не передает указатель на функцию. Я столкнулся с этой проблемой __only__ с указателями функций. Технически обе наши программы изоморфны 'int main();', но я передаю этот указатель функции по какой-то причине ... –

+0

@mic_e Я приводил пример о том, как ваша программа ведет себя аналогичным образом. Вычисление аргументов шаблона не выполняется, поэтому у моего конструктора есть подпись 'S (int, int)' так же, как ваш конструктор должен иметь 'S (void (*) (float, int))' при замене аргументов шаблона. – 0x499602D2

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

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