GCC 中的编译器错误,但在将 decltype 与具有尾随返回类型语法的模板化成员函数一起使用时没有 clang
compiler error in gcc but not clang when using decltype with templated member function with trailing return type syntax
我有一个带有模板化成员函数的类,该函数将可调用类型作为参数,并使用带有尾随返回类型语法的 decltype 从所提供函数的返回类型推导出返回类型。下面显示了一个最小示例。
#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;
}
此代码在 clang++ 和 g++-5 中按预期编译和工作,但在 g++-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 编译器错误还是 clang 错误地接受了上面的代码?如果这些函数签名之间有什么区别,该怎么办?为什么内联实现会有所不同?
是的,可能是GCC错误。解决方法是执行
template<typename T>
std::result_of<T(double)> point::eval(const T& in) {
这是因为您没有显式实例化模板函数定义。据我了解,它不是有效的 c++ 代码,编译器不必接受它。如果要在其他编译器上重现此错误,请尝试将类point
移动到头文件,并将定义point::eval
到.cpp文件中。因此,您要么必须为每种类型的参数显式实例化此定义(这对于 lambda 是不可能的),要么(正如我所建议的)除非迫切需要,否则不要使用外联模板。
相关文章:
- 助记符和指向成员语法的指针
- 我想获取点的属性,它报告错误 C3867:"point::output_x":非标准语法;使用"&"创建指向成员的指针
- 非标准语法,使用 & 创建指向成员的指针
- 错误 C2059:语法错误:从结构成员声明'constant'
- 非标准语法使用 '&' 创建指向成员 C++ 的指针
- 使用函数类型语法声明成员函数
- 没有数据成员和大括号语法的类的默认复制构造函数
- C++成员模板专用化语法
- WINAPI EnumWindowsProc:非标准语法;使用 & 创建指向成员的点
- 返回没有 typedef 的成员函数指针的语法是什么?
- 'cv::Mat::type':非标准语法;使用 '&' 创建指向成员的指针
- registerPointPickingCallback (PCLViewer::callback_Test,(void*)&viewer);返回 C3687 非标准语法;使用"&"创建指向成员的指针
- 复制构造函数语法错误:myclass 没有成员 mymember
- C++ Visual Studio 2015:非标准语法;使用 '&' 创建指向成员的指针
- 非标准语法;使用 & 创建指向成员的指针
- C++状态机,继承了具有语法不正确的成员值的类
- Visual Studio 2015"非标准语法;使用"&"为成员创建指针"
- 非标准语法;使用 '&' 创建指向成员的指针错误,将成员函数分配给向量时出错
- 具有数据成员语法的零成本属性
- c++静态类成员-语法错误