请考虑以下c ++代码:
#include <bits/stdc++.h>
template <typename T> void print_type() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
class Base{
int num;
public:
Base() : num{0} {}
friend std::ostream & operator << ( std::ostream& stream, Base & obiekt){
stream<< "num: " << obiekt.num;
return stream;
}
};
int main(){
Base a{};
std::cout << a << std::endl;
std::cout << "type of a: " << std::endl;
print_type < decltype( a ) > ();
std::cout << "type of (a): " << std::endl;
print_type < decltype( (a) ) > ();
Base b();
std::cout << b << std::endl;
std::cout << "type of b: " << std::endl;
print_type < decltype( b ) > ();
std::cout << "type of (b): " << std::endl;
print_type < decltype( (b) ) > ();
return 0;
}
我用g ++ 7.2.0编译它,得到以下输出:
num: 0
type of a:
void print_type() [with T = Base]
type of (a):
void print_type() [with T = Base&]
1
type of b:
void print_type() [with T = Base()]
type of (b):
void print_type() [with T = Base (&)()]
我的问题:
std::cout << b << std::endl;
打印“1”?Base()
或Base (&)()
?(a)
类型为Base&
时,为什么a
的类型为Base
?我正在寻找答案,我找不到它。我知道在这种情况下我应该使用Base a;
这样的声明而不使用任何括号,但我想知道Base a;
,Base a{};
和Base a();
之间的区别。为什么它没有任何警告或错误?
谢谢你的帮助。
答案 0 :(得分:4)
主要问题是:
Base b();
没有做你的想法。实际上,它是一个函数声明,它接受零参数并返回Base
类型的对象。
为什么std :: cout&lt;&lt; b&lt;&lt;的std :: ENDL;打印&#34; 1&#34;?
因为b
是指向函数的指针。结果,一个过载:
basic_ostream& operator<<( bool value );
使用并打印1
作为指向函数的指针永远不为空。
一个更有趣的问题是为什么gcc甚至接受代码并仅产生警告。函数b
没有定义,只有它的声明,所以我希望代码不要链接。
什么类型的类型如Base()或Base(&amp;)()?
Base()
是一个指向函数的指针,不接受任何参数并返回Base
,Base (&)()
是对同一函数的引用。
为什么类型(a)是Base&amp;,当a有类型Base?
因为decltype
works so:
decltype(expression)
如果参数是未加密集的 id-expression或者 未表示的类成员访问表达式,然后是decltype yield 此表达式命名的实体的类型。如果没有这样的话 实体,或者如果参数命名一组重载函数,则 节目形成不良。
如果参数是T类型的任何其他表达式,并且
a)如果表达式的值类别是xvalue,则decltype产生 T&安培;&安培;;
b)如果表达式的值类别是左值,则为decltype 产生T&amp; ;
c)如果表达式的值类别是prvalue,那么 decltype产生T。