GCC 11.1编译C++代码报错,求兼容方案及错误提示解析
问题解析与兼容方案
错误提示含义解释
GCC 11.1报错里的“use 'auto' for an abbreviated function template”是编译器的误判。你这里用std::tuple{...}是想借助C20的类模板实参推导(CTAD)让编译器自动推断tuple的模板参数,但GCC 11对CTAD的支持有局限——当你直接把std::tuple{...}作为函数(这里是light的构造函数)参数时,它错误地将这种写法识别成了试图定义缩写函数模板(C20里auto func(auto arg)这种简化模板函数的写法),所以给出了这个不相关的提示。
兼容GCC 11的可行方案
以下方案都不用手动指定tuple的模板参数,避免代码冗长:
方案1:先用auto变量存储tuple
先把tuple用auto推导类型后,再传给light构造函数,GCC 11支持auto变量的CTAD:
#include <cstdio> #include <tuple> template <typename T> struct channel { int a; T b; }; template <typename... Channels> struct light { light(const std::tuple<Channels...>& channels) : channels_(channels) { } std::tuple<Channels...> channels_; }; int main() { auto chans = std::tuple{channel(2, 2), channel(2,false)}; light li(chans); }
方案2:添加light类的推导指引
给light添加C++17/20的推导指引,让编译器能直接从传入的tuple参数推导light的模板参数,这样可以直接写初始化代码:
#include <cstdio> #include <tuple> template <typename T> struct channel { int a; T b; }; template <typename... Channels> struct light { light(const std::tuple<Channels...>& channels) : channels_(channels) { } std::tuple<Channels...> channels_; }; // 推导指引:告诉编译器从tuple的参数推导light的模板参数 template <typename... Channels> light(const std::tuple<Channels...>&) -> light<Channels...>; int main() { light li(std::tuple{channel(2, 2), channel(2,false)}); }
方案3:使用std::make_tuple(C++11及以上兼容)
std::make_tuple是C++11就有的工具,能自动推导元素类型,GCC 11完全支持:
#include <cstdio> #include <tuple> template <typename T> struct channel { int a; T b; }; template <typename... Channels> struct light { light(const std::tuple<Channels...>& channels) : channels_(channels) { } std::tuple<Channels...> channels_; }; int main() { light li(std::make_tuple(channel(2, 2), channel(2,false))); }
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

