专门化模板类的朋友(c++)
friend of specialized template class (C++)
#include <iostream>
using namespace std;
template <typename T>
class test
{
T y;
public:
test(T k) : y(k) {}
friend int a(T& x);
};
template <typename T>
int a(T& x)
{
cout << x.y;
return 9;
}
template <>
class test<int>
{
int y;
public:
test(int k) : y(k) {}
friend int a(int& x);
};
template <>
int a<int>(int& x)
{
cout << "4";
return 0;
}
int main(int argc, char* argv[])
{
test<int> z(3);
a(z);
return 0;
}
我想为test类创建一个朋友类(在实际情况中,它是一个运算符<<)ofstream)。但是我不知道如何定义专门化类的模板友元函数。
此外,上面的代码显示了编译错误消息;
错误C2248: 'test::y':不能访问声明的私有成员类的测试"
添加问题;
Aaron McDaid对我来说很好,但是我试图重载operator<<ofstream类的。
friend ofstream& operator<< <test<int>> (ofstream& os, const test<int>& t);
我将上面的代码添加到测试类和
template<>
ofstream& operator<< <test<int> > (ofstream& os, const test<int>& t)
{
os << t.y;
return os;
}
使用了上面的代码。但是看起来我不能用os <<t.y(这是int)我不明白为什么会发生这种情况。错误信息是
错误C2027:使用未定义类型'std::basic_ofstream<_element,_Traits>'
这个好友不是模板,而是一个普通的函数:
friend int a(T& x);
要想拥有一个同时也是友元的模板,试试:
template<class U>
friend int a(U& x);
在评论中的讨论之后,也许我应该表明我打算将这些声明用于test
类及其专门化:
template <typename T>
class test
{
T y;
public:
test(T k) : y(k) {}
template<class U>
friend int a(U& x);
};
template <>
class test<int>
{
int y;
public:
test(int k) : y(k) {}
template<class U>
friend int a(U& x);
};
一个轻微的缺点是,这使得所有a
函数的所有test
类的朋友,但这往往不是一个大问题
(更新:这是http://ideone.com/3KGU4上的完整测试版本。关于附加问题,请参见http://ideone.com/w0dLo)
普通的重载函数和模板函数有区别。例如,开发人员可以在不引用模板的情况下声明:
void f(int x);
void f(char *x);
或者,开发人员可以使用模板,
template <class T> void f(T x);
它们之间的一个主要区别是,对于普通函数,您必须事先决定一组固定的允许参数,并且必须为每个参数提供实现。使用模板,您可以更灵活。
在程序的后面,很明显您希望a
是一个模板函数,而不仅仅是一个(重载的)普通函数。但是,当编译器第一次看到提到a
时(大约在第10行左右),它看起来像是在声明一个普通的函数。要解决这个问题,必须采取两个步骤。必须尽快声明a
是一个模板函数,因此第一行应该是:
template <typename T> int a(T& x);
那么你必须声明相关的友谊。如果T
是int
,那么a
的参数是test<int>&
,而不是int&
。因此这两个友行应该替换为:
friend int a<test<T> >( test<T> & x); // around line 10
friend int a<test<int> >( test<int> & x); // around line 27
, a
的专门化应该是:
template <>
int a< test<int> >(test<int>& ) // around line 30
附加问题
使用ostream
而不是ofstream
(或者如果您只输出到文件而不输出到cout
,则包括#include <fstream>
)。在我的回答中,operator <<
不是模板,而是一个正常的重载函数。我不确定是否可以将operator<<
作为模板。此外,我在声明操作符的地方定义了操作符,并将其声明为友元。老实说,我认为还有其他更好的方法,但这对我来说很有效。
试试这个,它可以工作
#include <iostream>
using namespace std;
template <typename T>
class test;
template <typename T>
int a( test<T>& x);
template <typename T>
class test
{
T y;
public:
test(T k) : y(k) {}
friend int a<T>( test<T>& x);
};
template <typename T>
int a( test<T>& x)
{
cout << x.y;
return 9;
}
template <>
class test<int>
{
int y;
public:
test(int k) : y(k) {}
friend int a<int>( test<int> & x);
};
template <>
int a< int >( test<int> & x)
{
cout << "4";
return 0;
}
int main(int argc, char* argv[])
{
test<int> z(3);
a(z);
return 0;
}
问题是,模板函数a
接受了test
模板类的一个参数。如果你想让它们都有相同的模板参数,那么IMO你需要显式地声明
template <typename T>
int a( test<T>& x);
函数a
对int
(template<> int a(int& x)
)的专门化在这里也没有用。你需要有
template <> int a<int>( test<int> & x)
- 一位朋友将模板函数缩写为clang和gcc
- 班级的朋友是不可接近的
- 与朋友声明相反
- 为什么即使我声明了朋友类,我也会收到错误"无法访问类中声明的私人成员"
- 类似虚拟的朋友功能?
- 为什么C++需要公共继承,忽略朋友声明,才能使动态向下工作?
- 在朋友类中使用模板
- 访问私人成员而不使用朋友类
- 类和朋友在它们之间起作用
- "朋友"成员函数和 GCC 与 Clang
- 朋友声明的复杂范围界定规则有什么意义?
- C++:让函数成为多个类的朋友?
- 有没有办法C++将给定类的功能限制为仅另一个类(不使用继承,朋友)?
- 朋友,前瞻宣言,C++
- 在VS 2017中,朋友通过具有私有析构函数的结构的unique_ptr向量进行迭代失败
- 限制多模板参数朋友函数可访问的类实例的范围
- 朋友定义函数的名称空间是什么
- 朋友函数随机行为
- 从安卓NDK15切换到17使得malloc和朋友找不到
- 在课堂上创建了一个朋友,给出"无输入文件"错误