我想打印出一个用户定义类型的对象,就像cout << ob1;
这样我想重载operator <<并且我希望按值返回而不是通过引用但是它给了我一个错误:在两个名为iosfwd和ios_base的文件中. H
ostream operator<<( ostream& out, cat& rhs){
out << rhs.a << ", " << rhs.b << endl;
return out ;
}
Run Code Online (Sandbox Code Playgroud)
1)是因为它不能创建一个新的ostream对象,这就是为什么它必须通过引用返回?
但是当我像这样通过引用返回时:
ostream& operator<<( ostream& out, cat& rhs){
out << rhs.a << ", " << rhs.b << endl;
return out ;
}
Run Code Online (Sandbox Code Playgroud)
它工作正常.
2)有什么解释吗?
我想知道当我通过指定模板类型参数创建类模板的实例时.
1)为什么非被调用的函数没有得到实例化?.
2)在我尝试使用之前,他们不会被编译?
3)这种行为背后的逻辑是什么?
例
template <class T>
class cat{
public:
T a;
void show(){
cout << a[0];
}
void hello(){
cout << "hello() get called \n";
}
};
int main(){
cat<int> ob1; // I know that show() did not get instatiated, otherwise I will get an error since a is an int
ob1.hello();
}
Run Code Online (Sandbox Code Playgroud) 代码使用GCC编译.这项工作在VC++中没有任何错误
template <typename T>
void Function(T& A){
T::iterator it; //Error : dependent-name 'T::iterator' is parsed as a non-type,
//but instatiation yields a type.
}
Run Code Online (Sandbox Code Playgroud)
本文指出编译器无法弄清楚T类型中的迭代器是类还是静态成员.因此,我们必须使用typename关键字将符号分类为类型.
我的问题是,因为T在编译时已知,然后编译器已经知道iteratorT内部是一个类(在我的例子中是T vector<int>).那么为什么会有错误呢?
这也是typename关键字的另一种用途,旁边使用它来定义模板参数T.
更新:
我从这里读了所有答案和其他答案,真正回答了我的所有想法.我可以总结一下:
处理这个权利的正确编译器是Gcc.VC++将允许您编译格式错误的代码.使用Gcc编译时产生的错误是由于语法分析,因为Gcc将尝试解析函数模板的代码,但它会发现语法错误,这是T::iterator it;因为Deafault的Gcc将其T::iterator视为变量(T::iterator被解析为非变量)为了解决这个问题,你必须明确告诉Gcc将其T::iterator视为一种类型,这是通过添加关键字来完成的typename.
现在回到VC++.为什么这有效的答案是因为VC++中存在的错误,VC++是否会延迟决定T::iterator是变量还是类型.或VC++提供typename它认为必要的关键字.
有用的文章
注意:如果您发现不正确的内容,请随意编辑更新.
码:
#include<iostream>
using namespace std;
void foo() throw(char) {throw 'a';}
int main() try {
void (*pf)() throw(float);
pf = foo; // This should NOT work
pf();
}
catch(const char& c){cout << "Catched ::> " << c << endl;}
Run Code Online (Sandbox Code Playgroud)
为什么即使异常规范与函数指针不同,也可以传递foo给它?这是我的编译器中的错误吗?pffoopf
我有一个名为main.cpp包含的文件iostream.
我编译main.cpp和它的工作没有错误,所以我的问题是:我编main.cpp,我没有链接iostream有main.cpp,所以怎么会这样可能吗?或者编译器是否iostream自动链接?
const int &ra=3;
Run Code Online (Sandbox Code Playgroud)
正如我所知,制作raconst将延长临时r值的生命周期,在这种情况下为3.这有点令人困惑,因为我知道ra应该有与r值相同的地址,这里是3,但是3是不是一个真正的变量,它没有存储它的存储器.那怎么可能呢?
有什么区别:
const int& ra=a;
Run Code Online (Sandbox Code Playgroud)
和
int& const ra=a;
Run Code Online (Sandbox Code Playgroud)我有两个关于char数组的问题.
从下面的代码开始,既然arr是const,为什么编译器没有给我一个错误,因为我正在重写它?
char arr[5]; // arr is a const pointer to (*)[5] array
cin>>arr; //
Run Code Online (Sandbox Code Playgroud)当我初始化一个这样的char数组时:
char arr[5]={'h','i'};
Run Code Online (Sandbox Code Playgroud)
如果我这样做:
cout << arr << "something here \n";
Run Code Online (Sandbox Code Playgroud)
它会打印出来hisomething here.我以为它应该打印出来
hi something here
Run Code Online (Sandbox Code Playgroud)
有3个witespaces.
但如果我这样做:
for(int i = 0; i < 5; i++){
cout << arr[i];
}
Run Code Online (Sandbox Code Playgroud)
它会打印出3个空格.
第二种情况似乎证明编译器不添加任何空字符.那么编译器如何忽略3个空格呢?
我试图让A班成为B班的朋友.
class B;
class A{
public:
void show(const B&); // ##1## but this one works fine
B ob;// error incomplete type
};
class B{
public:
int b;
B():b(1){}
friend class A;
};
Run Code Online (Sandbox Code Playgroud)
所以我的问题为什么它是不完整的类型?我认为当我这样做时,class B它就像一个函数的原型,告诉编译在代码中的某个地方有一个定义.
也可以在上面的代码## 1 ##为什么这可能?
在缓冲流的情况下,它在一本书中说它等到缓冲区已满,然后写回监视器.例如:
cout << "hi";
Run Code Online (Sandbox Code Playgroud)
"缓冲区已满"是什么意思.
cerr << "hi";
Run Code Online (Sandbox Code Playgroud)在我的书中说,发送到的所有内容都会cerr立即写入标准错误设备,这是什么意思?
char *ch;
cin>> ch; // I typed "hello world";
Run Code Online (Sandbox Code Playgroud)在这个例子ch中将被分配为"hello"并且"world"将被忽略是否意味着它仍然在缓冲区并且它将影响未来语句的结果?