专用模板类的朋友 (C++)

发布于 2024-12-21 08:16:00 字数 1371 浏览 2 评论 0原文

#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;
}

我想创建一个测试类的友元类(在实际情况中,它是 ofstream 的运算符<<)。但我不知道如何定义专门类的模板友元函数。

此外,上面的代码显示了这个编译错误消息;

错误 C2248:“test::y”:无法访问在中声明的私有成员 类“测试”

已添加问题;

Aaron McDaid 对我来说效果很好,但我试图重载运算符<< 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 << ty (这是int)我不明白为什么会发生这种情况。错误信息是

错误 C2027:使用未定义类型“std::basic_ofstream<_Elem,_Traits>”

#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;
}

I want to make a friend class of test class (in a real case, it was a operator<< of ofstream). But I have no idea how to define template friend function of specialized class.

Besides, the code above shows this compile error message;

error C2248: 'test::y' : cannot access private member declared in
class 'test'

Question added;

Aaron McDaid works fine for me, but I was trying to overload operator<< of ofstream class.

friend ofstream& operator<< <test<int>> (ofstream& os, const test<int>& t);

I added code above to test class and

template<>
ofstream& operator<< <test<int> > (ofstream& os, const test<int>& t)
{
    os << t.y;
    return os;
}

used code above. But it looks like I cannot use os << t.y (which is int) I don't understand why this happens. The error message is

error C2027: use of undefined type 'std::basic_ofstream<_Elem,_Traits>'

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

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

发布评论

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

评论(3

金兰素衣 2024-12-28 08:16:00

这个朋友不是一个模板,而是一个普通的函数:

friend int a(T& x); 

要拥有一个同时也是朋友的模板,请尝试:

template<class U>
friend int a(U& x); 

在评论中的讨论之后,也许我应该表明我打算将这些声明用于测试 类及其特化:

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 类的朋友,但这通常不是一个大问题。

This friend isn't a template, but an ordinary function:

friend int a(T& x); 

To have a template that is also a friend, try:

template<class U>
friend int a(U& x); 

After the discussions in the comments, perhaps I should show that I intended these declarations for the test class and its specialization:

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 slight disadvantage is that this makes all the a functions friends of all the test classes, but that is often not a big problem.

仙女 2024-12-28 08:16:00

更新:这是 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);

然后你必须声明相关的友谊。如果 Tint,则 a 采用 test& 参数,而不是 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)。在我的回答中,operator << 不是模板,而是一个普通的重载函数。我不确定是否可以使用 operator<< 作为模板。另外,我在声明它的地方定义了该运算符并声明为友元。老实说,我认为还有其他,也许更好的方法,但这对我有用。

(Update: Here's a fully tested version on http://ideone.com/3KGU4. For the Additional question, see http://ideone.com/w0dLo)

There is a difference between ordinary overloaded functions and template functions. For example, without any reference to templates a developer can declare:

void f(int x);
void f(char *x);

Alternatively, a developer could use templates,

template <class T> void f(T x);

A major difference between them is that with ordinary functions, you must decide on a fixed set of allowed parameters in advance, and you must provide an implementation for each one. With templates, you can be more flexible.

Later in your program, it is clear that you want a to be a template function, not simply an (overloaded) ordinary function. But when the compiler first sees mention of a (around line 10), it looks like it is declaring an ordinary function. To resolve this, you must take two steps. You must declare as soon as possible that a is a template function, so your first line should be:

template <typename T> int a(T& x);

Then you must declare the relevant friendship. If T is int, then a takes a parameter of test<int>&, not int&. Therefore the two friend lines should be replaced with:

friend int a<test<T> >( test<T> & x); // around line 10
friend int a<test<int> >( test<int> & x); // around line 27

and the specialization of a should be:

template <>
int a< test<int> >(test<int>& ) // around line 30

The Additional Question

Use ostream instead of ofstream (or else include #include <fstream> if you will output only to files and not to cout). In my answer, operator << is not a template, but is a normal overloaded function. I'm not sure it's possible to have operator<< as a template. Also, I defined the operator at the place where it is declared and declared as a friend. To be honest, I think there are other, maybe better, ways but this worked for me.

女皇必胜 2024-12-28 08:16:00

试试这个,它可以工作

#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 接受一个参数 <代码>测试模板类。如果您希望它们都具有相同的模板参数,那么,在我看来,您需要明确声明

template <typename T>
    int a( test<T>& x);

函数 a for int 的特化 (template<>; int a(int& x)) 在这里没有用。你需要有

template <> int a<int>( test<int> & x)

Try this, and it works

#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;
}

The problem is, template function a takes a parameter of test template class. If you want both of them to have the same template argument then , IMO you need to explicitly state that

template <typename T>
    int a( test<T>& x);

Also specialization of function a for int (template<> int a(int& x)) isn't useful here. You need to have

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