Consider following c++ code:
#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;
}
I compiled it with g++ 7.2.0, and got following output:
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 (&)()]
My questions:
- Why std::cout << b << std::endl;prints "1"?
- What is a type like Base()orBase (&)()?
- Why type of (a)isBase&, whenahas typeBase?
I am looking for answer and I can't find it. I know in this case I should use declarations like Base a; without any brackets, but i want to know about difference between Base a;, Base a{}; and Base a();. Why it copiles without any warnings or errors?
Thanks for help.
 
    