模板类和插入提取重载

发布于 2024-10-01 09:35:16 字数 394 浏览 5 评论 0原文

如何使插入(<<)和/或提取(>>)运算符在模板类中重载而不使其内联。我想要<<或>>运算符作为友元类。 我知道如何使其内联 矩阵类中内联的示例

friend ostream& operator<<(ostream& ostr, const Matrix<T>& inputMatrix)
{
   ...
   // create the ostr
   return ostr;
}

,但我希望代码位于模板类定义之外。

g++ 告诉我添加 <>在函数名称之后,所以我这样做了,但是当我尝试实例化 SOMETYPE 类型的矩阵时,它给了我一个错误,它不知道如何提取或插入该类型。

How can I make the insertion (<<) and/or extraction (>>) operator overloaded in a template class WITHOUT making it inline. I would like to have the << or >> operator as a friend class.
I know how to make it inline
example of inline in a matrix class

friend ostream& operator<<(ostream& ostr, const Matrix<T>& inputMatrix)
{
   ...
   // create the ostr
   return ostr;
}

but I'd like to have the code outside of the templateclass definition.

g++ told me to add <> after the function name so I did but when I tried to instansiate a matrix of type SOMETYPE it gave me an error that it didn't know how to extract or insert for that type.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

以可爱出名 2024-10-08 09:35:16

如果您确实想在外部定义运算符并仅与与此模板实例化类型一致的运算符实例化,正确的语法是:

template <typename T> class test; // forward declare template class
template <typename T>              // forward declare the templated operator
std::ostream& operator<<( std::ostream&, test<T> const & );

template <typename T>
class test {                      // define the template
   friend std::ostream& operator<< <T>( std::ostream&, test<T> const & ); // befriend
};
template <typename T>              // define the operator 
std::ostream& operator<<( std::ostream& o, test<T> const & ) {
   return o;
}

在大多数情况下,考虑到您将定义从类中拉出,这是不值得的麻烦仍然需要在标头中提供它以及所需的额外工作。

另请注意,编译器在查找方面存在细微差别。如果函数内联在类定义中,编译器将找不到该函数除非其中一个参数实际上是模板的类型,因此它有效地降低了可见性和数量编译器必须完成的工作(如果模板化运算符<<是在类外部定义的,则编译器将在它找到的所有位置将其视为重载解析的候选者) a << b,仅在第二个参数不是 test 的所有情况下丢弃它(并且它将在所有错误中将模板化运算符显示为候选者)无法匹配 operator<< 的消息,这已经是一个足够长的列表了)。

If you really want to define the operator externally and befriend only the operator instantiation that coincides in type with this template instantiation, the correct syntax is:

template <typename T> class test; // forward declare template class
template <typename T>              // forward declare the templated operator
std::ostream& operator<<( std::ostream&, test<T> const & );

template <typename T>
class test {                      // define the template
   friend std::ostream& operator<< <T>( std::ostream&, test<T> const & ); // befriend
};
template <typename T>              // define the operator 
std::ostream& operator<<( std::ostream& o, test<T> const & ) {
   return o;
}

In most cases it is not worth the hassle to pull the definition out of the class, considering that you still need to provide it in a header and the extra work required.

Also note that there are slight differences for the compiler regarding lookup. In the case where the function is inlined inside the class definition, the compiler will not find that function unless one of the arguments is actually of the type of the template, so it effectively reduces the visibility and the amount of work that the compiler has to do (if the templated operator<< is defined outside of the class, the compiler will find it as a candidate for overload resolution in all places where it finds a << b, only to discard it in all cases where the second argument is not a test<T> (and it will show the templated operator as a candidate in all error messages where it cannot match operator<<, which is a long enough list already).

温柔女人霸气范 2024-10-08 09:35:16

尝试类似的操作:

template <typename T> class Matrix;
template <typename T> std::ostream& operator<<(std::ostream& ostr, const Matrix<T>& m);

template <Typename T>
class Matrix
{
    public:

        friend ostream& operator<< <T> (ostream& ostr, const Matrix<K>& inputMatrix);
};

// This must be in the same translation unit as the class definition!
template<typename T>
ostream& operator<<(ostream& ostr, const Matrix<T>& inputMatrix)
{
   // ...
   return ostr;
}

翻译单元参考

重新编辑以解决 aschepler 和 drbeas 提出的评论。

Try something like:

template <typename T> class Matrix;
template <typename T> std::ostream& operator<<(std::ostream& ostr, const Matrix<T>& m);

template <Typename T>
class Matrix
{
    public:

        friend ostream& operator<< <T> (ostream& ostr, const Matrix<K>& inputMatrix);
};

// This must be in the same translation unit as the class definition!
template<typename T>
ostream& operator<<(ostream& ostr, const Matrix<T>& inputMatrix)
{
   // ...
   return ostr;
}

Translation unit reference

re-re-edited to addressed the comments made by aschepler and dribeas.

梦亿 2024-10-08 09:35:16

将代码放置在类定义之外的标头中。或者,将其放入 .tcc 文件中并将其包含在标头的底部。

Place the code in the header, outside the class definition. Or, place it in a .tcc file and include it at the bottom of the header.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文