gpt4 book ai didi

C++ friend 模板函数 - minGW 错误但不是 VS2015

转载 作者:行者123 更新时间:2023-11-28 02:07:21 24 4
gpt4 key购买 nike

以下代码在 Visual Studio 2015 中编译没有问题,但在 minGW 中会出现如下所示的警告和错误:

#include <iostream>
using std::ostream;

template<typename ElemType, int SIZE>
class Array
{
friend ostream &operator<<(ostream &out, const Array<ElemType, SIZE> &value);

ElemType operator[](int index) const;

private:
ElemType elements[SIZE];
};

template<typename ElemType, int SIZE>
ostream &operator<<(ostream &out, const Array<ElemType, SIZE> &value);

template<typename ElemType, int SIZE>
ostream &operator<<(ostream &out, const Array<ElemType, SIZE> &value)
{
out << elements[0];
return out;
}

mingw32-g++.exe -Wall -g -pedantic-errors -pedantic -Wextra -Wall -std=c++98 -c Test.cpp
Test.cpp:7:79: warning: friend declaration 'std::ostream& operator<<(std::ostream&, const Array<ElemType, SIZE>&)' declares a non-template function [-Wnon-template-friend]
Test.cpp:7:79: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
Test.cpp: In function 'std::ostream& operator<<(std::ostream&, const Array<ElemType, SIZE>&)':
Test.cpp:21:11: error: 'elements' was not declared in this scope

我在这方面远不是专家,所以我不确定问题出在哪里。它似乎告诉我它需要在类本身的 friend 声明之前添加以下代码,但是当我把它放在那里时它会导致其他编译错误:

template<typename ElemType, int SIZE>

提前致谢!

按照@Trevor Hickey 在其下方的帖子中提出的更改建议进行更改后,关于 friend 模板功能的警告消失了。但是,我仍然收到有关未在范围内声明“元素”(在友元函数中)的错误。

最佳答案

您的代码中存在两个不同的问题。比较简单的是 out << elements[0];应该是 out << value.elements[0]; .这是因为您要打印属于参数 value 的元素。 .请记住,我们在这里处于非成员函数中,没有 this并且没有您可以通过非限定名称访问的成员。

另一个被称为 template friends problem .到目前为止你只得到一个警告,但是如果你试图编译一个完整的程序你会得到一个错误。我添加了代码:

int main() { Array<int, 5> a; std::cout << a; }

然后出现错误:

undefined reference to `std::ostream& operator<< <int, 5>(std::ostream&, Array<int, 5> const&)'

问题是你的代码:

friend ostream &operator<<(ostream &out, const Array<ElemType, SIZE> &value);

实际上声明了一个非模板 函数,它将成为Array 实例的友元。 .稍后,当你写 cout << amain ,编译器匹配 <<到这个非模板声明。它永远不会达到 operator<< 的正文您稍后提供的,因此永远不会实例化该主体的拷贝,因此出现 undefined reference 错误。

解决此问题的一种方法是显式实例化主体。但这很蹩脚,因为您必须为 Array 的每个可能实例化编写一个显式实例化。发生在您的代码中。所以我们不会这样做。

最简单的解决方案是将 operator<< 的主体放在在类定义中内联。

另一种选择是声明 operator<<是模板函数。

Trevor Hickey 的代码展示了一种方法,尽管它有一个缺点 Array<A, B>::elements可以通过 Array<C, D>::operator<< 访问.

更安全的方法是声明 operator<<课前:

template<typename ElemType, int SIZE>
class Array;

template<typename ElemType, int SIZE>
ostream &operator<<(ostream &out, const Array<ElemType, SIZE> &value);

然后是你之前的其余代码。现在,friend类中的声明将匹配预先存在的模板,而不是声明一个新的非模板。

关于C++ friend 模板函数 - minGW 错误但不是 VS2015,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36974166/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com