2015-02-09 102 views
5

我有以下代碼:C++ 11 decltype:如何聲明指針指向的類型?

#include <memory> 

int main() 
{ 
    int* a = new int(2); 

    std::unique_ptr<decltype(*a)> p(a); 
} 

從而導致這些錯誤消息:

In file included from a.cpp:1: 
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/memory:81: 
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/unique_ptr.h:138:14: error: '__test' declared as a pointer to a reference of type 'int &' 
      static _Tp* __test(...); 
        ^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/unique_ptr.h:146:35: note: in instantiation of member class 'std::unique_ptr<int &, 
     std::default_delete<int &> >::_Pointer' requested here 
     typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type; 
           ^
a.cpp:7:35: note: in instantiation of template class 'std::unique_ptr<int &, std::default_delete<int &> >' requested here 
    std::unique_ptr<decltype(*a)> p(a); 
           ^
In file included from a.cpp:1: 
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/memory:81: 
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/unique_ptr.h:227:33: error: 'type name' declared as a pointer to a reference of type 'int &' 
       is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> 
            ^
a.cpp:7:35: note: in instantiation of template class 'std::unique_ptr<int &, std::default_delete<int &> >' requested here 
    std::unique_ptr<decltype(*a)> p(a); 
           ^
2 errors generated. 

我理解的原因是模板的unique_ptr預計鍵入int,但decltype(*a)int&。如果int是一個非常長和複雜的類型,我該如何使這個代碼與decltype一起工作?

+0

'的std ::的unique_ptr <性病:: pointer_traits :: ELEMENT_TYPE> P(A);'' – 2015-02-09 08:02:19

回答

13

使用std::decay_t。這是在按值傳遞參數給函數時應用的轉換。

+0

std :: unique_ptr :: type> p(a);'工作! – xuhdev 2015-02-09 08:07:56

+0

'std :: unique_ptr > p(a);'對於C++ 14,'std :: unique_ptr > p (一);'也行得通。 – cbel 2015-02-09 08:26:17

4

可以使用一個typedef一個模板類中,然後使用模板專業化,這樣

template<typename T> struct unref { 
    typedef T raw; 
}; 
template<typename T> struct unref<T&> { 
    typedef T raw; 
}; 

int main() { 
    int* a = new int(2); 
    std::unique_ptr<unref<decltype(*a)>::raw> p(a); 
} 
+0

您需要添加'* struct * unref',並且您在第二個模板定義之後錯過了分號。 – 2015-02-09 08:10:12

+0

在C++ 11中,存在std :: remove_reference。 – cbel 2015-02-09 08:25:16

+0

@cbel當然,在C++ 11之前,還有一些boost工具可以做同樣的事情。這更多的是「教一個人釣魚」類型的答案...... – 2015-02-09 08:26:40