Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different types of `decltype((const int)a)` and `decltype((const int)1)`

// g++ 7.3
template<typename T>
struct td;

int main()
{
  int a = 1;

  td<decltype((const int)a)> t1;
  td<decltype((const int)1)> t2;

  return 0;
}

Below is the output of compilation:

error: aggregate ‘td<int> t1’ has incomplete type and cannot be defined
error: aggregate ‘td<const int> t2’ has incomplete type and cannot be defined

So, why are the types of decltype((const int)a) and decltype((const int)1) different?

like image 489
olist Avatar asked May 28 '18 04:05

olist


2 Answers

The specifiers decltype((const int)a) and decltype((const int)1) both resolve to int. This is because there are no const prvalues of non-class type, as covered in C++17 [expr]:

If a prvalue initially has the type cv T, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.

Your output might just be a bug in the diagnostic message. To confirm a compiler bug you could write some code whose behaviour differs depending on the decltype result, e.g.:

decltype((const int)1) x;  x = 5;

which should compile successfully.

like image 170
M.M Avatar answered Nov 18 '22 14:11

M.M


Not an answer, just additional data.

The following code,

template< class Type > struct T{ Type x; };

int main()
{
    int a = 1;
    T<decltype((const int)a)> t1; t1.x = 1;
    T<decltype((const int)1)> t2; t2.x = 2;
}

… compiles cleanly with Visual C++ 2017, but not with MinGW g++ 7.2.0:

[P:\temp]
> g++ foo.cpp
foo.cpp: In function 'int main()':
foo.cpp:7:31: error: use of deleted function 'T<const int>::T()'
     T<decltype((const int)1)> t2; t2.x = 2;
                               ^~
foo.cpp:1:31: note: 'T<const int>::T()' is implicitly deleted because the default definition would be ill-formed:
 template< class Type > struct T{ Type x; };
                               ^
foo.cpp:1:31: error: uninitialized const member in 'struct T<const int>'
foo.cpp:1:39: note: 'const int T<const int>::x' should be initialized
 template< class Type > struct T{ Type x; };
                                       ^
foo.cpp:7:42: error: assignment of read-only member 'T<const int>::x'
     T<decltype((const int)1)> t2; t2.x = 2;
                                          ^

[P:\temp]
> _

This indicates a g++ compiler bug.

like image 43
Cheers and hth. - Alf Avatar answered Nov 18 '22 14:11

Cheers and hth. - Alf