如何在模板类范围内定义模板运算符?

How can I define a template operator inside a template class scope?

本文关键字:定义 运算符 范围内      更新时间:2024-05-09

>我正在尝试"模板化"的矩阵类有问题。这个想法是能够乘以两个不同类型的矩阵,而无需显式重载乘法方法。例如,假设我们有一个type A和一个type B。如果我将matrix<A>乘以matrix<B>,如果我知道乘以元素type A * type B给了我一个type B那么matrix<A>*matrix<B>应该给我一个matrix<B>(我希望很清楚)。

话虽如此,我部分解决了我的问题std::common_type.在我尝试实现 *= 运算符之前,我的代码表现良好(如果您注释 *= 相关部分,您将看到)。这是一个简单的代码,可以重现我当前的错误:

#ifndef MATRICE_H
#define MATRICE_H
#include <typeinfo>
#include <type_traits>
#include <iostream>
template<typename T1>
class Matrice
{
private:
T1 table;
public:
T1 getTable(){return table;}
Matrice(T1 m_table);
//template<typename T2>
//Matrice<T1>& operator *= (Matrice<T2>&);
};
template<typename T1, typename T2, typename T3>
Matrice<T3> operator*(Matrice<T2>&, Matrice<T1>&);
template<typename T1, typename T2>
Matrice<T1>& Matrice<T1>::operator *= (const Matrice<T2>& B);
#endif

和身体:

#include "Matrice.h"
template<typename T1>
Matrice<T1>::Matrice(T1 m_table):table(m_table)
{
}
template<typename T1, typename T2>
Matrice<typename std::common_type<T1,T2>::type> operator * (Matrice<T2>& M2, Matrice<T1>& M1)
{   

typename std::common_type<T1,T2>::type tab3= (M1.getTable())*(M2.getTable());
return Matrice<typename std::common_type<T1,T2>::type>(tab3);
}
template<typename T1, typename T2>
Matrice<T1>& Matrice<T1>::operator *= (const Matrice<T2>& B)
{
table = (typename T1) table*(B.getTable())
}
int main()
{
float tab1(12.5);
int tab2(11);
Matrice<float> M1(tab1);
Matrice<int> M2(tab2);
Matrice<float> M3 =  M1*M2;
std::cout << M3.getTable() << std::endl;
M3*=M2;
return 0;
}

我收到以下镜像错误,感觉就像 c++ 之神在拖钓:

Matrice.h:26:6: error: no declaration matches 'void Matrice<T1>::operator*=(Matrice<T2>&)'
26 | void Matrice<T1>::operator *= (Matrice<T2>& B);
Matrice.cpp:18:6: error: no declaration matches 'void Matrice<T1>::operator*=(Matrice<T2>&)'
18 | void Matrice<T1>::operator *= (Matrice<T2>& B)

和显而易见的

Matrice.cpp: In function 'int main()':
Matrice.cpp:31:7: error: no match for 'operator*=' (operand types are 'Matrice<float>' and 'Matrice<int>')
31 |     M3*=M2;

备注:我尝试寻找这些错误,我只看到了我大多不理解的模糊相关内容。例如这里:定义一个模板函数,采用模板类的参数 请温柔一点,这是我的第一次模板冒险!

附加问题:每次在代码中显示时,TypeName std::common_type<T1,T2>::type是否都会被评估,或者结果是否以某种方式被记住?我可能会将大矩阵相乘,并且我想避免数千次计算类型名称std::common_type<T1,T2>::type以获得恒定的结果。

编辑:此处提供的示例只是重现错误的最小代码

EDIT2:类定义中的注释运算符 *= 只是我迄今为止为规避错误而尝试的各种事情的痕迹

你遇到了一些问题。我认为这些变化是不言自明的。如果没有,请告诉我。 神霹雳: https://godbolt.org/z/ErMdbfEnc

#include <typeinfo>
#include <type_traits>
#include <iostream>
template<typename T1>
class Matrice
{
private:
T1 table;
public:
const T1 & getTable() const
{
return table;
}
T1 & getTable()
{
return table;
}
Matrice(T1 m_table);
template<typename T2>
Matrice<T1>& operator *= ( const Matrice<T2>& );
};
template<typename T1, typename T2, typename T3>
Matrice<T3> operator*(Matrice<T2>&, Matrice<T1>&);
// template<typename T1>
// template<typename T2>
// Matrice<T1>& Matrice<T1>::operator *= (const Matrice<T2>& B);
template<typename T1>
Matrice<T1>::Matrice(T1 m_table):table(m_table)
{
}
template<typename T1, typename T2>
Matrice<typename std::common_type<T1,T2>::type> operator * (Matrice<T2>& M2, Matrice<T1>& M1)
{   

typename std::common_type<T1,T2>::type tab3= (M1.getTable())*(M2.getTable());
return Matrice<typename std::common_type<T1,T2>::type>(tab3);
}
template<typename T1>
template<typename T2>
Matrice<T1>& Matrice<T1>::operator *= (const Matrice<T2>& B)
{
table = (T1) table*(B.getTable());
return *this;
}
int main()
{
float tab1(12.5);
int tab2(11);
Matrice<float> M1(tab1);
Matrice<int> M2(tab2);
Matrice<float> M3 =  M1*M2;
std::cout << M3.getTable() << std::endl;
M3*=M2;
return 0;
}