2015-02-09 6 views
5

Ich habe den folgenden Code:C++ 11 decltype: Wie deklariert man den Typ, auf den ein Zeiger zeigt?

#include <memory> 

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

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

, die zu dieser Fehlermeldung führt:

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. 

Ich verstehe, der Grund dafür ist, dass die unique_ptr Vorlage int Typ erwartet, aber decltype(*a) gibt int&. Für den Fall, dass int ein sehr langer und komplizierter Typ ist, wie kann ich diesen Code mit declltype arbeiten lassen?

+0

'std :: unique_ptr :: ELEMENT_TYPE> p (a) verwenden;' ' –

Antwort

13

Verwenden Sie std::decay_t. Dies ist die Konvertierung, die angewendet wird, wenn Sie ein Argument nach Wert an eine Funktion übergeben.

+0

std :: unique_ptr :: type> p (a); 'funktioniert! – xuhdev

+0

'std :: eindeutiges_ptr > p (a);' für C++ 14, 'std :: eindeutiges_ptr > p (a); 'funktioniert auch. – cbel

4

Sie können eine typedef in einer Templat-Klasse verwenden und dann Template-Spezialisierung, wie diese

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

Sie müssen '* struct * unref 'hinzufügen und Sie haben ein Semikolon nach der zweiten Vorlagedefinition verpasst. –

+0

In C++ 11 existiert std :: remove_reference. – cbel

+0

@cbel Sicher, und vor C++ 11 gab es Boost-Utilities, um das Gleiche zu tun. Das war eher eine Antwort vom Typ "Teach a Man to fish" ... –

Verwandte Themen