У меня есть класс с шаблонизированной функцией-членом, которая принимает вызываемый тип в качестве аргумента и имеет тип возвращаемого значения, выводимый из возвращаемого типа поставляемая функция с использованием decltype с синтаксисом типа возвращаемого типа возврата. Ниже приведен минимальный пример.ошибка компилятора в gcc, но не clang при использовании decltype с templated member function с типом возвращаемого типа возвращаемого значения
#include <iostream>
#include <vector>
class point {
public:
std::vector<double> val;
point(double in) : val({in}) {};
template<typename T> auto eval(const T& in) -> decltype(in(val[0]));
};
template<typename T>
auto point::eval(const T& in) -> decltype(in(val[0])){
return in(val[0]);
}
int main(int argc, char *argv[]){
point pt(2.0);
auto f = [](double x){return x*x;};
std::cout << pt.val[0] << std::endl;
std::cout << pt.eval(f) << std::endl;
}
Этот код компилируется и работает, как ожидалось в звоном ++ и г ++ - 5, но дроссели со следующей ошибкой в г ++ - 6.
> g++-6 main.cpp -o test -std=c++11 -Wall main.cpp:13:6: error:
> prototype for 'decltype
> (in(0->((point*)this)->point::val.std::vector<_Tp,
> _Alloc>::operator[]<double, std::allocator<double> >())) point::eval(const T&)' does not match any in class 'point' auto
> point::eval(const T& in) -> decltype(in(val[0])){
> ^~~~~ main.cpp:9:35: error: candidate is: template<class T> decltype (in(0->((point*)this)->point::val.std::vector<_Tp,
> _Alloc>::operator[]<double, std::allocator<double> >())) point::eval(const T&)
> template<typename T> auto eval(const T& in) -> decltype(in(val[0]));
> ^~~~ main.cpp:9:35: error: 'decltype (in(0->((point*)this)->point::val.std::vector<_Tp,
> _Alloc>::operator[]<double, std::allocator<double> >())) point::eval(const T&) [with T = main(int, char**)::<lambda(double)>;
> decltype (in(0->((point*)this)->point::val.std::vector<_Tp,
> _Alloc>::operator[]<double, std::allocator<double> >())) = double]', declared using local type 'const main(int, char**)::<lambda(double)>',
> is used but never defined [-fpermissive] main.cpp:9:35: warning:
> 'decltype (in(0->((point*)this)->point::val.std::vector<_Tp,
> _Alloc>::operator[]<double, std::allocator<double> >())) point::eval(const T&) [with T = main(int, char**)::<lambda(double)>]'
> used but never defined make: *** [all] Error 1
Ошибка компилятора не отображается, если реализация написана рядный, т.е.
template<typename T> auto eval(const T& in) -> decltype(in(val[0])){
return in(val[0]);
}
Кроме того, в C++ 14 с использованием автоматического типа возврата дедукции путем изменения подписи
template<typename T> auto eval(const T& in);
работает должным образом.
Является ли это ошибкой компилятора gcc или неверно принимает вышеуказанный код? Что делать, если какая-либо разница между этими сигнатурами функций? Почему встраивание реализации имеет значение?
Несомненно, ошибка gcc. – ildjarn