Различные типы `decltype ((const int) a)` и `decltype ((const int) 1)` - PullRequest
0 голосов
/ 28 мая 2018
// 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;
}

Ниже приведены результаты компиляции:

ошибка: агрегат ‘td<int> t1’ имеет неполный тип и не может быть определен
ошибка: агрегат ‘td<const int> t2’ имеет неполный тип и не может быть определен

Итак, почему типы decltype((const int)a) и decltype((const int)1) отличаются?

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Не ответ, просто дополнительные данные.

Следующий код,

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;
}

… скомпилирован без ошибок с Visual C ++ 2017, но не с 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]
> _

Это указывает на ошибку компилятора g ++.

0 голосов
/ 28 мая 2018

Спецификаторы decltype((const int)a) и decltype((const int)1) оба разрешают до int.Это связано с тем, что const значений типа non-class нет, как описано в C ++ 17 [expr]:

Если значение prvalue изначально имеет тип cv T, где T является неквалифицированным cv неклассом, не относящимся к массиву типом, тип выражения корректируется до T перед любым дальнейшим анализом.

Ваш вывод может быть просто ошибкой вдиагностическое сообщениеЧтобы подтвердить ошибку компилятора, вы можете написать некоторый код, поведение которого отличается в зависимости от результата decltype, например:

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

, который должен успешно скомпилироваться.

...