Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 decltype: How to declare the type that a pointer points to?

Tags:

c++

c++11

I have the following code:

#include <memory>

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

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

which leads to these error message:

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.

I understand the reason is that the unique_ptr template expects type int, but decltype(*a) gives int&. In the case that int is a very long and complicated type, how can I make this code work with decltype?

like image 883
xuhdev Avatar asked Feb 09 '15 07:02

xuhdev


People also ask

What is the return type of decltype?

If the expression parameter is a call to a function or an overloaded operator function, decltype(expression) is the return type of the function. Parentheses around an overloaded operator are ignored. If the expression parameter is an rvalue, decltype(expression) is the type of expression .

What is decltype keyword in C++?

In the C++ programming language, decltype is a keyword used to query the type of an expression. Introduced in C++11, its primary intended use is in generic programming, where it is often difficult, or even impossible, to express types that depend on template parameters.

What is the difference between auto and decltype in C++?

'auto' lets you declare a variable with a particular type whereas decltype lets you extract the type from the variable so decltype is sort of an operator that evaluates the type of passed expression.

Is runtime a decltype?

decltype is a compile time evaluation (like sizeof ), and so can only use the static type.


2 Answers

Use std::decay_t. This is the conversion that is applied when you pass an argument to a function by value.

like image 104
Pradhan Avatar answered Oct 03 '22 16:10

Pradhan


You can use a typedef inside a templated class and then use template specialisation, like this

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);
}
like image 26
Michael Anderson Avatar answered Oct 03 '22 16:10

Michael Anderson