如何让C++调用模板化operator()而非误判为小于运算符?
GCC泛型lambda模板化operator()调用的编译错误解决
在C++20泛型lambda代码中,GCC会将模板化operator()的调用误判为小于运算符,导致编译失败。
原代码(注:代码中vs为笔误,应改为vector):
void scale_vector(std::vector<int>& vector, int scale) { auto visitor = [&]<int scale_const>() { for (int& v : vector) { // 原代码此处为vs,已修正 v *= scale_const; } }; switch (scale) { case 1: visitor<1>(); break; case 2: visitor<2>(); break; case 3: visitor<3>(); break; case 4: visitor<4>(); break; default: throw std::runtime_error("invalid scale"); } }
使用-O3 -std=c++20编译时,GCC trunk报错:
<source>: In function 'void scale_vector(std::vector<int>&, int)': <source>:14:20: error: no match for 'operator<' (operand types are 'scale_vector(std::vector<int>&, int)::<lambda()>' and 'int') 14 | visitor<1>(); | ~~~~~~~^~ | | | | | int | scale_vector(std::vector<int>&, int)::<lambda()> <source>:14:24: error: expected primary-expression before ')' token 14 | visitor<1>(); | ^
错误原因
编译器将visitor<1>解析为visitor < 1(小于运算符比较),而非对lambda模板化operator()的参数指定。常规的template关键字无法直接使用,因为lambda本身不是模板类型,仅其内部的operator()是模板函数。
解决方法
显式调用lambda的模板化operator(),明确指定模板参数即可修正编译错误。
修正后的调用片段
switch (scale) { case 1: visitor.operator()<1>(); break; case 2: visitor.operator()<2>(); break; case 3: visitor.operator()<3>(); break; case 4: visitor.operator()<4>(); break; default: throw std::runtime_error("invalid scale"); }
完整修正代码
#include <vector> #include <stdexcept> void scale_vector(std::vector<int>& vector, int scale) { auto visitor = [&]<int scale_const>() { for (int& v : vector) { v *= scale_const; } }; switch (scale) { case 1: visitor.operator()<1>(); break; case 2: visitor.operator()<2>(); break; case 3: visitor.operator()<3>(); break; case 4: visitor.operator()<4>(); break; default: throw std::runtime_error("invalid scale"); } }
内容的提问来源于stack exchange,提问作者Clueless
相关产品推荐
相关产品推荐

