Переменные шаблона с классом в качестве имени типа

#c #templates #c 14

#c #шаблоны #c 14

Вопрос:

Я изучаю C 14, в котором сталкиваюсь с этой функцией переменной шаблона, и это заинтересовало меня, чтобы узнать больше об этом, и я попытался на нескольких примерах понять переменные шаблона. Скажем,

 template <typename T>
T var;

var<int>;
var<float>;

  

Приведенный выше код работал, и он тоже выглядел понятным. Но, когда я попытался использовать имя класса вместо int или float, как показано выше, это привело к вызову создания временного объекта для класса FOO и вызову соответствующий C’tor amp; dtor для временного объекта.

 var<FOO>;  //FOO is a class
  

Я написал пример тестовой программы и ее вывод для вашего понимания. Мой вопрос заключается в том, что,

  1. Почему var создает временный объект?
  2. Чем переменная шаблона отличается для примитивных типов данных и пользовательских типов данных?

Если это не имеет значения или дублируется, пожалуйста, укажите мне источник для ясного понимания.

См. Код ниже,

 class B
{
  public:
  B()
  {
      std::cout<<"nB ctor"<<std::endl;
  }
  B(const Bamp; obj)
  {
      std::cout<<"B copy ctor"<<std::endl;
  }
  int operator()()
  {
      std::cout<<"operator() called"<<std::endl;
  }
   void f()  {
   //::A().print();   
  }
  ~B()
  {
      std::cout<<"n~ for B()"<<std::endl;
  }
  
};

//Declaring template variable
template<typename T>
 T g ;

int main() {
    g<int> = 30;
    g<float> = 30.02f;
    g<B> = B{};
    std::cout<<"g value:"<<g<int><<std::endl;
    std::cout<<"g value:"<<g<float>;
}
  

Вывод:

 B ctor                                                                                                                                         
g value:30                                                                                                                                     
g value:30.02                                                                                                                                  
~ for B()   
  

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

1. 1. var сам по себе не создает временный объект. 2. Это не так.

Ответ №1:

Эта простая программа не создает временных объектов:

 int main() {
  var<SomeClass>;
}
  

Здесь создается временный объект:

 int main() {
  var<SomeClass> = SomeClass{};
}
  

но это потому, что мы сделали это с SomeClass{} . Затем мы присвоили это var<SomeClass> не временному объекту (глобальному во многих ваших примерах).

Выполняемый здесь код

  SomeClass::SomeClass()
 SomeClass::SomeClass()
 SomeClass::operator=(SomeClassamp;amp;)
 SomeClass::~SomeClass()
 SomeClass::~SomeClass()
  

в таком порядке.

 #include <iostream>

struct noisy {
  noisy() { std::cout << __func__ << "()n"; }
  ~noisy() { std::cout << __func__ << "()n"; }
  noisy(noisyamp;amp;) { std::cout << __func__ << "(amp;amp;)n"; }
  noisy(noisy constamp;) { std::cout << __func__ << "(camp;)n"; }
  void operator=(noisyamp;amp;) { std::cout << __func__ << "(amp;amp;)n"; }
  void operator=(noisy constamp;) { std::cout << __func__ << "(camp;)n"; }
};

template<class T>
T var;

int main() {
    std::cout << "Start of mainn";
    {
        var<noisy> = noisy{};
        std::cout << "Body of mainn";
    }
    std::cout << "End of mainn";
}
  

живой пример.

Вывод:

 noisy()
Start of main
noisy()
operator=(amp;amp;)
~noisy()
Body of main
End of main
~noisy()