C ++模板朋友运算符重载 [英] C++ template friend operator overloading

查看:182
本文介绍了C ++模板朋友运算符重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码有什么问题?

 模板< int E,int F& 
class Float
{
friend Float< E,F&运算符+(const Float< E,F>& lhs,const Float< E,F&
};

G ++只是警告:



code> float.h:7:warning:friend声明'Float< E,F>运算符+(const Float< E,F& amp; const Float< E,F&)声明非模板函数



float.h:7:warning:(如果这不是你想要的,请确保函数模板已经被声明,并在这里的函数名后添加<>)-Wno- template-friend禁用此警告



我试图添加<后面的函数名称这里如在警告中提到的,但g ++给我一个错误。



我编译代码与clang ++,

解决方案

这只是一个关于语言棘手问题的警告。当你声明一个 friend 函数时,它不是声明所在的类的成员。为了方便起见,可以定义它,但它实际上属于命名空间。 / p>

声明一个不是模板的朋友函数,在类模板中,仍然在命名空间中声明一个非模板函数。它既不是类的成员,也不是模板。



从模板生成非模板函数有点朦胧。例如,您不能在块之外为该函数添加声明。因此,你必须在 class 块中定义它,这是有道理的,因为类模板会生成它。



关于朋友的另一个棘手的事情是, class Float {} 中的声明不会在命名空间中声明函数。你只能通过参数依赖意义重载解析,即指定一个参数类型 Float (或引用或指针)找到它。这不是 operator + 的问题,因为它可能会被重载,除非用户定义类型,它将永远不会被调用。



有一个潜在问题的例子,假设你有一个转换构造函数 Float :: Float(Bignum const&)。但是 Bignum 没有 operator + 。 (对不起,设计的例子。)你想依赖 operator +(Float const& Float const&) for Bignum 加成。现在 my_bignum + 3 将无法编译,因为操作数都不是 Float ,因此找不到朋友函数。



可能没有什么可担心的,只要所讨论的函数是



或者,您也可以将 friend 变更为范本。在这种情况下,必须在 class {} 块之外定义并在其之前声明,而不需要声明和定义 > inside

 模板< int E,int F& //现在这是一个模板! 
Float< E,F>运算符+(const Float< E,F>& lhs,const Float< E,F&

template< int E,int F>
class Float
{
//推导参数E和F - 这个名称运算符+< E,F。
friend Float< E,F> operator +<> (const Float< E,F>& lhs,const Float< E,F&
};


What is wrong with my code?

template<int E, int F>
class Float
{
 friend Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);
};

G++ just keeps warning:

float.h:7: warning: friend declaration ‘Float<E, F> operator+(const Float<E, F>&, const Float<E, F>&)’ declares a non-template function

float.h:7: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning

I tried to add <> after the function name here as mentioned in the warning note, but g++ gives me an error.

I compiled the code with clang++, it was fine, no warning at all.

解决方案

It's just a warning about a tricky aspect of the language. When you declare a friend function, it is not a member of the class the declaration is in. You can define it there for convenience, but it actually belongs to the namespace.

Declaring a friend function which is not a template, inside a class template, still declares a non-template function in the namespace. It is neither a member of the class, nor itself a template. However, it is generated by the class template.

Generating non-template functions from a template is a bit hazy. For example, you cannot add a declaration for that function outside the class block. Therefore you must define it inside the class block as well, which makes sense because the class template will generate it.

Another tricky thing about friends is that the declaration inside class Float {} does not declare the function in the namespace. You can only find it through argument-dependent meaning overload resolution, i.e. specifying an that an argument has type Float (or a reference or pointer). This is not an issue for operator+, as it is likely to be overloaded anyway, and it will never be called except for with user-defined types.

For an example of a potential issue, imagine you have a conversion constructor Float::Float( Bignum const& ). But Bignum does not have operator+. (Sorry, contrived example.) You want to rely on operator+(Float const&, Float const&) for Bignum addition. Now my_bignum + 3 will not compile because neither operand is a Float so it cannot find the friend function.

Probably, you have nothing to worry about, as long as the function in question is an operator.

Or, you can change the friend to be a template as well. In that case, it must be defined outside the class {} block, and declared before it, instead of needing to be declared and defined inside.

template<int E, int F> // now this is a template!
Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);

template<int E, int F>
class Float
{
  // deduce arguments E and F - this names operator+< E, F >.
 friend Float<E, F> operator+<> (const Float<E, F> &lhs, const Float<E, F> &rhs);
};

这篇关于C ++模板朋友运算符重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆