C++ std::declval <utility> (tcy)

1.1.定义:
   template<class T>           
   typename std::add_rvalue_reference<T>::type declval() noexcept; (since C++11)           

1.2.用途:
   将任何类型转为引用类型,从而可用在decltype表达式而无需通过构造函数 
           
1.3.说明:
   1)declval通常在模板中使用;模板参数可能没有构造函数,但具有返回类型的函数
   2)不管是否有没有默认构造函数或该类型不可以创建对象。(可以用于抽象基类);
 
1.4.参数:无           

1.5.返回值:  
    无法调用不会有返回值。
    返回类型为T&&除非T是(可cv限定)void,在这种情况下,返回类型为T            

1.6.注意:
   declval只能在未评估的上下文中使用,只在编译期间生效的语句里
   不需要定义,不需要类型T 拥有构造函数;评估包含此函数的表达式是错误的

1.7.备注: 
   表达式有两种属性:值与类型。值与类型也是两种不同的数据。
   decltype作用于表达式,返回表达式类型
   declval作用于类型,返回该类型的表达式(准确来说是该类型加上右值引用类型)

   常用的C语言方式*(T*) nullptr 也能获得类型为T的表达式
   由于不存在引用指针这种类型,所以如果T是引用类型时,

   using R = int &;
 
   //std::declval<R>()++ 表达式类型为int, ++std::declval<R>() 表达式类型为int&&
   decltype(std::declval<R>()++) i=1;    
 
   //decltype(*(R*)nullptr) j = m;//错误
   cout << i << endl;   

2.实例: 
实例1:         
 #include <utility>           
 #include <iostream>           
            
 struct A { int foo() const {return 1;}};                      
 struct B{B() = delete;int foo() const {return 1;}};           
            
 int main(){           
  decltype(A().foo()) n1 = 1;                // type of n1 is int           
 //  decltype(B().foo()) n2 = n1;            // 错误无默认构造函数           
  decltype(std::declval<B>().foo()) n2 = n1; // type of n2 is int                      
 }           
实例2:
 #include <utility>      
 #include <iostream>    
  
 struct Base {virtual int get_x() = 0;};
  
 class B : public Base {   
  public:
     B(int i,int j):x(i*j){}
     int get_x() {return x;}
  private:
     int x;
 };
  
 int main(){
   decltype(std::declval<Base>().get_x()) a;  // int a;
   decltype(std::declval<B>().get_x()) b;     // int b;
   decltype(B(0,0).get_x()) c;                // int c;
   a = b = B(10,2).get_x();
   std::cout << a << '\n';
 }

 

 

 

 

上一篇:decltype,decltype(auto) (tcy)


下一篇:利用__declspec(dllexport)和__declspec(dllimport)在Windows平台编写和使用DLL的小例子