Search code examples
c++decltype

decltype error C2440 cannot convert from 'int *' to 'int *&'


The following is a contrived example of the actual code:

int** Ptr = 0;
decltype(Ptr[0]) Test = (int*)0;

I get the error:

error C2440: 'initializing': cannot convert from 'int *' to 'int *&'

I'm not sure why I'm getting that since from my understand of decltype (correct me if I'm wrong) it just takes whatever expression you give it and resolve it to its actual type. In this case Ptr[0] is an int* so I'm expecting: int* Test = (int*)0;

What am I missing? Why am I getting that error?


Solution

  • If we go to the draft C++ standard section 7.1.6.2 Simple type specifiers [dcl.type.simple] and see what the cases are, for decltype it starts out saying:

    For an expression e, the type denoted by decltype(e) is defined as follows:

    We see that in this case the expression is not an id-expression nor a class member access, which would give the result you expected(emphasis mine):

    • if e is an unparenthesized id-expression or an unparenthesized class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;

    but the result is an lvalue:

    • otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;

    which results in a reference.

    As M.M point out std::remove_reference could be used to obtain the result you want:

    std::remove_reference<decltype(Ptr[0])>::type Test = (int*)0;
    

    As T.C. points out std::decay is also an option and is shorter:

    std::decay<decltype(Ptr[0])>::type Test = (int*)0;