GCC 8.1.0中类模板的模板实参推导失效问题
Hey,我来帮你搞定这个跨编译器的问题!你的代码在Clang能跑但GCC不行,主要是两个坑在搞鬼,咱们一步步理清楚:
问题根源与修复方案
第一个坑:命名冲突
你写了using namespace std;之后,自定义的vector就和标准库的std::vector撞名了。Clang在模板上下文里可能优先认你自定义的那个,但GCC的名字查找规则会先匹配到标准库的std::vector,这就直接导致编译报错——毕竟你这个自定义vector和标准库的模板结构完全不一样,编译器肯定懵。
第二个坑:完美转发的语法写错了
你构造函数里的std::forward...是不完整的,正确的完美转发得写成std::forward<Ps>(ps)...,得明确指定模板参数,还要把参数包展开才行。
修复后的完整代码
#include <tuple> #include <string> // 直接给自定义类型改个名字,彻底避开和std::vector的冲突 template <class... Ts> struct PropertyVector { using tuple_type = std::tuple<Ts...>; tuple_type properties; template <class... Ps> PropertyVector(Ps&&... ps) : properties(std::forward<Ps>(ps)...) {} // 修正后的完美转发写法 }; // 测试示例 int main() { PropertyVector<int, std::string> my_vec(42, "hello"); return 0; }
额外的小建议
- 尽量别在全局作用域或者头文件里用
using namespace std;,这是命名冲突的重灾区 - 如果非得保留
vector这个名字,那把它放到自己的命名空间里就行:
namespace my_tags { template <class... Ts> struct vector { using tuple_type = std::tuple<Ts...>; tuple_type properties; template <class... Ps> vector(Ps&&... ps) : properties(std::forward<Ps>(ps)...) {} }; } // 使用时通过命名空间区分 int main() { my_tags::vector<int, std::string> my_vec(42, "hello"); return 0; }
这样改完之后,不管是GCC 7.3.0、8.1.0还是Clang 6.0,都能正常编译运行啦~
内容的提问来源于stack exchange,提问作者CapSel
相关产品推荐
相关产品推荐

