- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为我创建的模板化堆栈类重载输出流运算符 (<<)(作为编程任务)。我正在使用向堆栈类声明友元运算符 << 函数的正常范例。我遵循了 Prata 的“将模板友元函数绑定(bind)到模板类”的示例(C++ primer plus)。代码编译并执行,但没有给出预期的结果,因为模板化运算符 << 函数试图重载 main 中每次出现的输出流运算符,而我只希望它重载 Stack 类的输出流运算符.所以我认为我需要专门化重载的 operator<< 函数。
我构建了一个更简单的代码示例来演示该问题。请注意,我没有在示例中使用重载的运算符<<,而是使用了一个名为“oper()”的函数。代码如下(也附上),问题是 oper() 适用于 Bigger 类(我想要)和 BIG 类(我不想要)。你能告诉我如何专门化模板化的 oper() 函数吗?
// Compiler: gcc
// Purpose: test templates. test bound template friend fns.
#include <iostream>
using namespace std;
// declare template function
template <typename T> std::ostream & oper (std::ostream &os, const T &);
template <typename T> class Bigger {
T value;
public:
Bigger(T init) {value = init;}
// declare bound template friend functions
friend std::ostream &oper<> (std::ostream &os, const Bigger<T> &);
};
class Bad { // but oper() can work with this class too!
int i;
public:
int value;
Bad(): i(1),value(2) {};
};
// define full template functions
// want to specialize this function so that it only works with class Bigger!
template <typename T> std::ostream &oper (std::ostream &os, const T & big) {
os << big.value;
return os;
}
int main (int argc, char * argv[]) {
Bigger <float> bf {3.1};
// this is desired behavior. oper() acts as a friend to Bigger.
cout << "oper bf: "; oper(cout,bf); cout<<endl;
Bad bad;
// this is undesired behavior. template is too loose allowing oper to work for Bad!!!
cout << "oper bad: ";oper(cout,bad);cout<<endl;
return 0;
}
最佳答案
how do I specialize a bound template friend function to a template class?
简单的回答你不能。函数模板只能完全专门化,但您所要求的是提供类似于类模板的部分专门化。最接近的是提供一个不同的基本模板(参见 Petr Budnik 的回答)而不是专门化......但我也不会那样做。
在定义模板的友元运算符(或一般的友元函数)时,我不喜欢使用模板,而是将单个非模板运算符定义为模板的友元。这可以在语言中通过在类定义中提供友元函数的定义来实现:
template <typename T>
class MyTemplate {
int data;
//...
friend std::ostream operator<<(std::ostream& os, MyTemplate const& t) {
os << t.data;
return os;
}
};
这种方法有几个优点,第一个是它允许为非模板函数提供通用实现,从而避免函数模板特化引起的所有问题(注意:避免特化函数模板!)和定义重载的多个基本函数模板,等等。同时,它在只能通过 ADL 查找找到它们的上下文中创建这些函数,这意味着它不会污染其他上下文,从而简化错误消息(或至少不会使它们进一步复杂化)。
关于c++ - 如何将绑定(bind)的模板友元函数特化到模板类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18279726/
我是一名优秀的程序员,十分优秀!