Преобразования квалификации C — постоянство и шаблоны

#c

#c

Вопрос:

В приведенном ниже коде я пытаюсь выяснить, почему компилятор (msdev c 2010 и Comeau) не рассматривает возвращаемый тип неспециализированной функции get шаблона как const . Я ожидал бы, что СЛУЧАЙ # 2 (см. code snipet) НЕ будет компилироваться, но это происходит. Есть идеи или ссылки?

Спасибо, регу

 template < typename T >
struct constness
{
  T value;
  constness() : value(0) {}
  const T amp;get() { return value; }
};

template < typename T >
struct constness< T * >
{
   T * const value;
   constness() : value(0) {}
   const T * const amp;get() { return value; }
};

int main( int argc, const char* argv[] )
{
  // Uses specialized
  constness< double * > wConstness;
  const_cast< double * amp; >(wConstness.value) = new double(1);
  *wConstness.get() = 12.0; // CASE #1 doesn't compile

  // Uses non specialized 
  constness< double * const > wConstness2;
  const_cast< double * amp; >(wConstness2.value) = new double(1);
  *wConstness2.get() = 12.0; // CASE #2 compiles, allowing modification of 
                             // value pointed by wConstness2.value

  return 0;
};
  

Комментарии:

1. const_cast< double * >(wConstness2.value) = new double(1); неверно: целевой тип приведения должен быть double*amp; , чтобы иметь значение lvalue, которому вы можете присвоить.

2. ого! … здесь уже слишком поздно: D

Ответ №1:

Вы создаете экземпляр constness с помощью T = double * const (указателя с постоянным значением на неконстантный параметр double ).

В const Tamp; get() , const применяется ко всему T . Если бы T было int* , то const T было бы int* const , а не const int* . Итак, в вашем конкретном случае const не имеет никакого эффекта, потому что T уже имеет значение const (это double* const ).

Когда у вас есть имя типа, подобное T , добавление const или volatile к имени типа всегда применяется на верхнем уровне, независимо от типа. Итак, const T и T const всегда одинаковы, независимо от того, что T такое.

Комментарии:

1. Спасибо за объяснение, к сожалению, это означает, что мой дизайн не будет работать: D