模板的模板友元函数 class
template friend functions of template class
我有以下模板 class 和旨在访问 class' 私有数据成员的模板函数:
#include <iostream>
template<class T>
class MyVar
{
int x;
};
template<class T>
void printVar(const MyVar<T>& var)
{
std::cout << var.x << std::endl;
}
template<class T>
void scanVar(MyVar<T>& var)
{
std::cin >> var.x;
}
struct Foo {};
int main(void)
{
MyVar<Foo> a;
scanVar(a);
printVar(a);
return 0;
}
为了将这两个函数声明为MyVar<T>
的友元函数,我在template<class T> class MyVar
的声明中尝试了以下方法来声明友元。 None 其中有效。我该怎么办?
template<class T> friend void printVar(const MyVar&);
template<class T> friend void scanVar(MyVar&);
// compilation error
template<class T> friend void printVar(const MyVar<T>&);
template<class T> friend void scanVar(MyVar<T>&);
// compilation error
friend void printVar(const MyVar<T>&);
friend void scanVar(MyVar<T>&);
// link error
friend void printVar(const MyVar&);
friend void scanVar(MyVar&);
// link error too
我成功完成了以下工作
#include <iostream>
template<class T>
class MyVar;
template<class T>
void printVar(const MyVar<T>& var);
template<class T>
void scanVar(MyVar<T>& var);
template<class T>
class MyVar
{
int x;
friend void printVar<T>(const MyVar<T>& var);
friend void scanVar<T>(MyVar<T>& var);
};
template<class T>
void printVar(const MyVar<T>& var)
{
std::cout << var.x << std::endl;
}
template<class T>
void scanVar(MyVar<T>& var)
{
std::cin >> var.x;
}
struct Foo {};
int main(void)
{
MyVar<Foo> a;
scanVar(a);
printVar(a);
return 0;
}
UPD: http://en.cppreference.com/w/cpp/language/friend 与 "Template friend operators":
下的运算符讨论了类似的情况
A common use case for template friends is declaration of a non-member
operator overload that acts on a class template, e.g.
operator<<(std::ostream&, const Foo<T>&)
for some user-defined
Foo<T>
Such operator can be defined in the class body, which has the effect
of generating a separate non-template operator<<
for each T
and
makes that non-template operator<<
a friend of its Foo<T>
...
or the function template has to be declared as a template before the
class body, in which case the friend declaration within Foo<T>
can
refer to the full specialization of operator<<
for its T
这个是在MSVC2013上编译的。基本上将前向声明添加到 class 并在 friend
之前运行
template<class T> class MyVar ; // class forward declaration
template<class T> ; // function forward declarations
void printVar(const MyVar<T>& var);
template<class T>
void scanVar(MyVar<T>& var);
template<class T>
class MyVar
{
friend void printVar<T>(const MyVar<T>&);
friend void scanVar<T>(MyVar<T>&);
int x;
};
template<class T>
void printVar(const MyVar<T>& var)
{
std::cout << var.x << std::endl;
}
template<class T>
void scanVar(MyVar<T>& var)
{
std::cin >> var.x;
}
struct Foo {};
int main1(void)
{
MyVar<Foo> a;
scanVar(a);
printVar(a);
return 0;
}
最简单的选项是在 class:
中定义好友
template<class T>
class MyVar
{
int x;
friend void printVar(const MyVar & var) {
std::cout << var.x << std::endl;
}
friend void scanVar(MyVar & var) {
std::cin >> var.x;
}
};
缺点是函数只能通过依赖于参数的查找来调用。这在您的示例中不是问题,但如果它们没有合适的参数,或者您想指定名称而不调用它,则可能会出现问题。
如果你想要一个单独的定义,那么模板必须在 class 定义之前声明(因此它可用于友元声明),但在之后定义(因此它可以访问 class 成员)。 class 也必须在函数之前声明。这有点乱,所以我只展示两个功能之一:
template <typename T> class MyVar;
template <typename T> void printVar(const MyVar<T> & var);
template<class T>
class MyVar
{
int x;
friend void printVar<T>(const MyVar<T> & var);
};
template <typename T> void printVar(const MyVar<T> & var) {
std::cout << var.x << std::endl;
}
好吧,有一个解决方案既简单又涉及友元函数的声明和定义之间的分离。在 friend 函数的声明中(在 class 内),你必须给出一个与 class 接受的模板参数不同的模板参数(这是有道理的,因为这个函数不是这个 class).
template<class T>
class MyVar
{
int x;
template<typename Type>
friend void printVar(const MyVar<Type> & var);
template<typename Type>
friend void scanVar(MyVar<Type> & var);
};
template<typename T>
void printVar(const MyVar<T> & var) {
}
template<typename T>
void scanVar(MyVar<T> & var) {
}
不需要前向声明,并且声明和定义是分开的。
我有以下模板 class 和旨在访问 class' 私有数据成员的模板函数:
#include <iostream>
template<class T>
class MyVar
{
int x;
};
template<class T>
void printVar(const MyVar<T>& var)
{
std::cout << var.x << std::endl;
}
template<class T>
void scanVar(MyVar<T>& var)
{
std::cin >> var.x;
}
struct Foo {};
int main(void)
{
MyVar<Foo> a;
scanVar(a);
printVar(a);
return 0;
}
为了将这两个函数声明为MyVar<T>
的友元函数,我在template<class T> class MyVar
的声明中尝试了以下方法来声明友元。 None 其中有效。我该怎么办?
template<class T> friend void printVar(const MyVar&);
template<class T> friend void scanVar(MyVar&);
// compilation error
template<class T> friend void printVar(const MyVar<T>&);
template<class T> friend void scanVar(MyVar<T>&);
// compilation error
friend void printVar(const MyVar<T>&);
friend void scanVar(MyVar<T>&);
// link error
friend void printVar(const MyVar&);
friend void scanVar(MyVar&);
// link error too
我成功完成了以下工作
#include <iostream>
template<class T>
class MyVar;
template<class T>
void printVar(const MyVar<T>& var);
template<class T>
void scanVar(MyVar<T>& var);
template<class T>
class MyVar
{
int x;
friend void printVar<T>(const MyVar<T>& var);
friend void scanVar<T>(MyVar<T>& var);
};
template<class T>
void printVar(const MyVar<T>& var)
{
std::cout << var.x << std::endl;
}
template<class T>
void scanVar(MyVar<T>& var)
{
std::cin >> var.x;
}
struct Foo {};
int main(void)
{
MyVar<Foo> a;
scanVar(a);
printVar(a);
return 0;
}
UPD: http://en.cppreference.com/w/cpp/language/friend 与 "Template friend operators":
下的运算符讨论了类似的情况A common use case for template friends is declaration of a non-member operator overload that acts on a class template, e.g.
operator<<(std::ostream&, const Foo<T>&)
for some user-definedFoo<T>
Such operator can be defined in the class body, which has the effect of generating a separate non-template
operator<<
for eachT
and makes that non-templateoperator<<
a friend of itsFoo<T>
...
or the function template has to be declared as a template before the class body, in which case the friend declaration within
Foo<T>
can refer to the full specialization ofoperator<<
for itsT
这个是在MSVC2013上编译的。基本上将前向声明添加到 class 并在 friend
之前运行template<class T> class MyVar ; // class forward declaration
template<class T> ; // function forward declarations
void printVar(const MyVar<T>& var);
template<class T>
void scanVar(MyVar<T>& var);
template<class T>
class MyVar
{
friend void printVar<T>(const MyVar<T>&);
friend void scanVar<T>(MyVar<T>&);
int x;
};
template<class T>
void printVar(const MyVar<T>& var)
{
std::cout << var.x << std::endl;
}
template<class T>
void scanVar(MyVar<T>& var)
{
std::cin >> var.x;
}
struct Foo {};
int main1(void)
{
MyVar<Foo> a;
scanVar(a);
printVar(a);
return 0;
}
最简单的选项是在 class:
中定义好友template<class T>
class MyVar
{
int x;
friend void printVar(const MyVar & var) {
std::cout << var.x << std::endl;
}
friend void scanVar(MyVar & var) {
std::cin >> var.x;
}
};
缺点是函数只能通过依赖于参数的查找来调用。这在您的示例中不是问题,但如果它们没有合适的参数,或者您想指定名称而不调用它,则可能会出现问题。
如果你想要一个单独的定义,那么模板必须在 class 定义之前声明(因此它可用于友元声明),但在之后定义(因此它可以访问 class 成员)。 class 也必须在函数之前声明。这有点乱,所以我只展示两个功能之一:
template <typename T> class MyVar;
template <typename T> void printVar(const MyVar<T> & var);
template<class T>
class MyVar
{
int x;
friend void printVar<T>(const MyVar<T> & var);
};
template <typename T> void printVar(const MyVar<T> & var) {
std::cout << var.x << std::endl;
}
好吧,有一个解决方案既简单又涉及友元函数的声明和定义之间的分离。在 friend 函数的声明中(在 class 内),你必须给出一个与 class 接受的模板参数不同的模板参数(这是有道理的,因为这个函数不是这个 class).
template<class T>
class MyVar
{
int x;
template<typename Type>
friend void printVar(const MyVar<Type> & var);
template<typename Type>
friend void scanVar(MyVar<Type> & var);
};
template<typename T>
void printVar(const MyVar<T> & var) {
}
template<typename T>
void scanVar(MyVar<T> & var) {
}
不需要前向声明,并且声明和定义是分开的。