0

I have a problem here: I am again reading C++ primer 5 edition. Now I am at std::allocator everything is Ok but I don't know why my code here doesn't copmile:

#include <iostream>
#include <initializer_list>
#include <memory>
#include <vector>


void print_vec(vector<int> v) {
    for (const auto i : v)
        std::cout << i << ", ";
    std::cout << std::endl;
}


int main(int argc, char* argv[]) {


    //print_vec(5); // fails. vector(size_t) is explicit

    std::allocator<vector<int>> a;
    auto p = a.allocate(10);
    a.construct(p, 5);// works?!

    //a.construct(p + 1, {7, 16, 23, 81, 77, 24, 10}); // doesn't work even vector(initilizer_list) is not explicit
    a.construct(p + 1, vector<int>({7, 16, 23, 81, 77, 24, 10 })); // works

    for (int i = 0; i != 2; ++i) {
        for (const auto& e : *(p + i))
            std::cout << e << ", ";
        std::cout << std::endl;
    }


    a.destroy(p);
    a.destroy(p + 1);
    a.deallocate(p, 10);


    std::cout << std::endl;
}
  • Why calling print_vec passing an integer doesn't compile -because I guess that the constructor of vector(size_type) is explicit then why calling a.construct(p, 5); works? as long as this value 5 is passed in to the constructor of vector to create 5 value-initialized integer elements.

  • Second I can call print_vec passing in an initializer_list<int> (vector(initializer_list) is not explicit ctor) but why this statement doesn't compile: a.construct(p + 1, {7, 16, 23, 81, 77, 24, 10});?

Itachi Uchiwa
  • 3,044
  • 12
  • 26
  • 1
    TL;DR of the dupe: `{ stuff }` has no type. You cant pass something to a template that doesn't have a type. – NathanOliver Nov 06 '19 at 21:17
  • You can pass an `initializer_list` to `construct`. `{...}` isn't an `initializer_list`. – chris Nov 06 '19 at 21:22
  • @NathanOliver-ReinstateMonica But why `a.construct(p, 5);` works? – Itachi Uchiwa Nov 06 '19 at 21:59
  • Because `5` has a type. It is `int`. If you tried `a.construct(p, {5});` it would also fail – NathanOliver Nov 06 '19 at 22:00
  • @NathanOliver-ReinstateMonica: I've visited the link you marked and saw that I can specify explicitly the element type: `a.construct>(p + 1, { 7, 16, 23, 81, 77, 24, 10 });` but again this doesn't work` – Itachi Uchiwa Nov 06 '19 at 22:06
  • 1
    @ItachiUchiwa That work around wont work because `construct` is a variadic template. – NathanOliver Nov 06 '19 at 22:12
  • @NathanOliver-ReinstateMonica: Ok thank you. So I have to explicitly pass an initializer list: `a.constrcut(p + 1, std::initializer_list{1,2,3,4});` This works. – Itachi Uchiwa Nov 06 '19 at 22:13
  • 1
    Simply you have to specify the element type for both `vector` followed by `initializer_list`: `a.construct, initializer_list>(p + 1, {7, 16, 23, 81, 77, 24, 10});` This should work because you told to the compiler that the second argument to `construct` is an `initializer_list`. – Raindrop7 Nov 06 '19 at 22:40

0 Answers0