模板类的多参数模板友元operator*函数编译报错求解
错误原因
你声明的operator*是包含3个模板参数(std::size_t s、typename T、typename U)的函数模板,而类内的友元声明只指定了1个模板参数U,剩余的s、T无法和类的模板参数正确匹配,且operator * <>的写法需要对应到已声明的模板特化,参数数量不匹配就会触发编译报错。
解决方案
方案1:类外实现+权限严格(推荐)
如果需要把operator*的实现放在类外,同时只想开放权限给对应当前A<s,T>实例的operator*,可以调整函数模板的参数顺序,把独立参数U放在最前面,方便编译器推导匹配:
#include <cstddef> template<std::size_t s, typename T> class A; // 调整模板参数顺序,把U放在第一位 template<typename U, std::size_t s, typename T> A<s, T> operator *(U const lhs, A<s, T> const& rhs); template<std::size_t s, typename T> class A { // Blabla // 仅给对应当前A<s,T>的operator*实例开放友元权限 template<typename U> friend A<s, T> operator * <U> (U const lhs, A<s, T> const& rhs); }; // 类外实现 template<typename U, std::size_t s, typename T> A<s, T> operator *(U const lhs, A<s, T> const& rhs) { A<s, T> res; // 你的运算逻辑 return res; }
方案2:类内定义(代码最简)
如果不需要单独做前置声明,可以直接把operator*的实现放在类内部,无需额外处理模板匹配逻辑,且权限天然严格:
#include <cstddef> template<std::size_t s, typename T> class A { // Blabla template<typename U> friend A operator*(U const lhs, A const& rhs) { A res; // 你的运算逻辑 return res; } };
方案3:全量友元声明(快速修复)
如果不需要严格控制权限,也可以直接声明所有operator*模板实例为友元,修改成本最低:
#include <cstddef> template<std::size_t s, typename T> class A; template<std::size_t s, typename T, typename U> A<s, T> operator *(U const lhs, A<s, T> const& rhs); template<std::size_t s, typename T> class A { // Blabla // 开放友元权限给所有operator*模板实例 template<std::size_t _s, typename _T, typename U> friend A<_s, _T> operator * (U const lhs, A<_s, _T> const& rhs); }; // 类外实现 template<std::size_t s, typename T, typename U> A<s, T> operator *(U const lhs, A<s, T> const& rhs) { A<s, T> res; // 你的运算逻辑 return res; }
内容的提问来源于stack exchange,提问作者Oussama Ennafii
相关产品推荐
相关产品推荐

