用decltype理解类型推导

时间:2018-02-03 20:43:46

标签: c++ reference

请考虑以下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();之间的区别。为什么它没有任何警告或错误? 谢谢你的帮助。

1 个答案:

答案 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()是一个指向函数的指针,不接受任何参数并返回BaseBase (&)()是对同一函数的引用。

  

为什么类型(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。