模板参数阴影与朋友
Template parameter shadows with friend?
在下面的例子中,重载<< operator
:
#include <iostream>
template <typename T>
class MyClass {
public:
MyClass(T X, T Y):x(X), y(Y) {}
template <typename U>
friend std::ostream& operator <<(std::ostream &os, const MyClass<U> &cl);
private:
T x;
T y;
};
template <typename T>
std::ostream& operator <<(std::ostream &os, const MyClass<T> &cl)
{
os << cl.x << " " << cl.y;
return os;
}
int main()
{
MyClass<int> cl(1, 2);
std::cout << cl << std::endl;
}
我已经搜索了其他问题,但我找不到为什么我需要:
template <typename U>
friend std::ostream& operator <<(std::ostream &os, const MyClass<U> &cl);
U
而不是T
typename
?因为最终U
和T
都是ints
.
你不能再次使用template <typename T>
,因为在行的其余部分,它不知道你的意思是两个T
中的哪一个。有点像这样,这也是一个错误:
void foo(int x) {
int x = 4;
cout << x; // which x?
}
编译器不够聪明,无法弄清楚在这种情况下,您将始终希望两个T
相同,就像上面foo
函数中的错误不会消失一样,如果您只在程序中调用foo(4)
。
但是您在这里意识到的是,您实际上根本不需要模板参数来operator<<
!那是因为在这种情况下,您确切地知道要使用哪种类型,whch 是MyClass<T>
.通常,当您知道所需的确切类型时,您可以摆脱模板参数。这称为显式专用化,通常如下所示:
template <>
friend std::ostream& operator<< <T>(std::ostream& os, const MyClass<T> &cl);
请注意空模板参数列表 template <>
,上面写着"我不需要模板参数",然后是函数名称后面的<T>
,上面写着"因为我希望模板参数类型完全T
",其中T
在MyClass
模板的特定实例中已经知道。但是,这在这里不起作用,因为C++语言规范中只有一条规则,即friend
声明中不允许显式专用化。(我不确定这条规则背后的理由是什么,但这是一个规则。
由于您不能重用标识符T
,并且不能显式专用化,因此剩下的唯一选择是对模板参数使用其他标识符,例如 U
。
相关文章:
- 一位朋友将模板函数缩写为clang和gcc
- 班级的朋友是不可接近的
- 与朋友声明相反
- 为什么即使我声明了朋友类,我也会收到错误"无法访问类中声明的私人成员"
- 类似虚拟的朋友功能?
- 为什么C++需要公共继承,忽略朋友声明,才能使动态向下工作?
- 在朋友类中使用模板
- C++声明模板参数阴影模板参数错误
- 访问私人成员而不使用朋友类
- 类和朋友在它们之间起作用
- "朋友"成员函数和 GCC 与 Clang
- DirectX 11 - 点光源阴影
- 朋友声明的复杂范围界定规则有什么意义?
- C++:让函数成为多个类的朋友?
- 有没有办法C++将给定类的功能限制为仅另一个类(不使用继承,朋友)?
- 朋友,前瞻宣言,C++
- 深度缓冲区未填充阴影贴图渲染通道中的数据
- 在VS 2017中,朋友通过具有私有析构函数的结构的unique_ptr向量进行迭代失败
- 限制多模板参数朋友函数可访问的类实例的范围
- 模板参数阴影与朋友