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

后端 未结 2 478
南方客
南方客 2021-01-18 17:08

The following is a contrived example of the actual code:

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

I get the error:

相关标签:
2条回答
  • 2021-01-18 17:56

    In addition to all the other answers, you may also just use

    int ** ptr = 0;
    decltype(+ptr[0]) test = (int*)0;
    // (+*p) is now an r-value expression of type int, rather than int&
    

    Some of the rules used here are:

    • if the value category of expression is lvalue, then decltype yields T&;
    • if the value category of expression is prvalue, then decltype yields T.

    Also note that if the name of an object is parenthesized, it is treated as an ordinary lvalue expression, thus decltype(x) and decltype((x)) are often different types. [an excerpt from https://en.cppreference.com/w/cpp/language/decltype]

    seen at http://www.cplusplus.com/forum/beginner/149331/
    more on decltype here : https://en.cppreference.com/w/cpp/language/decltype

    0 讨论(0)
  • 2021-01-18 18:04

    If we go to the draft C++ standard section 7.1.6.2 Simple type specifiers [dcl.type.simple] and see what he 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 a 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;
    
    0 讨论(0)
提交回复
热议问题