sta*_*ame 6 c++ templates overloading class friend
我有一个类需要有多个 * 运算符的重载。其中一些需要声明为朋友,以便我可以将类类型作为第二个参数。这是一个遇到我即将提出的问题的类的示例:
#pragma once
template<typename T>
class Example;
template<typename T>
Example<T> operator*(T value, Example<T> obj);
template<typename T>
class Example
{
private:
T m_data;
public:
Example(T);
friend Example operator*<T>(T, Example);
Example operator*(const T& other);
};
template<typename T>
Example<T> operator*(T value, Example<T> obj)
{
return value * obj.m_data;
}
template<typename T>
Example<T>::Example(T data) :m_data(data) { }
template<typename T>
Example<T> Example<T>::operator*(const T& other)
{
return Example(m_data * other.m_data);
}
Run Code Online (Sandbox Code Playgroud)
这有效,但如果我改变:
template<typename T>
class Example
{
private:
T m_data;
public:
Example(T);
friend Example operator*<T>(T, Example);
Example operator*(const T& other);
};
Run Code Online (Sandbox Code Playgroud)
和
template<typename T>
class Example
{
private:
T m_data;
public:
Example(T);
Example operator*(const T& other);
friend Example operator*<T>(T, Example);
};
Run Code Online (Sandbox Code Playgroud)
即使我所做的只是交换包含运算符重载声明的那两行,我也开始收到一堆错误。你能解释一下这里发生了什么吗?这对我来说毫无意义。
产生错误的代码:
Example<int> a(2);
2 * a;
Run Code Online (Sandbox Code Playgroud)
错误:
Run Code Online (Sandbox Code Playgroud)unexpected token(s) preceding';' syntax error missing':' before '<' 'operator*': redefinition: previous definition was 'function' 'operator*': looks like a function but there is no parameter list. '*': uses 'Example<int>' which is being defined '*': friend not permitted on data declarations
operator*您的代码中有两个不同的名称。有您在 之前声明的函数模板Example,以及 的成员函数Example。语法operator*<T>,模板特化,仅在operator*引用模板时有效,而不是成员函数。在你的第一个声明,其中friend谈到的成员函数前,operator*会员功能尚未在哪里编译器看到点声明operator*<T>,所以它解析名称的函数模板声明之前Example,一切都很好(具体专业化operator*<T>成为friend的每个Example<T>)。
template<typename T>
Example<T> operator*(T value, Example<T> obj); // <-\ ...finds a template, so no syntax error
// |
template<typename T> // |
class Example { // |
T m_data; // |
public: // |
Example(T); // |
friend Example operator*<T>(T, Example); // >-/ looking up this name...
Example operator*(const T& other);
};
Run Code Online (Sandbox Code Playgroud)
做它的其他方式,而是operator*<T>采取了被引用的成员函数,这是不是一个模板,你会得到一个语法错误(具体而言,我认为这是试图以某种方式把它解释为operator* < T >,其中<和>是实际低于/大于运算符)。
template<typename T>
class Example {
T m_data;
public:
Example(T);
Example operator*(const T& other); // <-\ ...does not find a template; ouch!
friend Example operator*<T>(T, Example); // >-/ looking up this name...
};
Run Code Online (Sandbox Code Playgroud)
在您的帮助下,我找到了以下解决方案。我还能够摆脱第一行中多余的声明。这是最终产品:
template<typename T>
class Example
{
private:
T m_data;
public:
Example(T);
Example operator*(const T& other);
template<typename T>
friend Example<T> operator*(T, Example<T>);
};
template<typename T>
Example<T> operator*(T value, Example<T> obj)
{
return value * obj.m_data;
}
template<typename T>
Example<T>::Example(T data) :m_data(data) { }
template<typename T>
Example<T> Example<T>::operator*(const T& other)
{
return Example(m_data * other.m_data);
}
Run Code Online (Sandbox Code Playgroud)