0

My code includes the following, and I get the error message above based on the last line below.

struct List {
    int word_i;
    int mod_i;
    char mod_type;
    char mod_char;
};

struct Morph {
    Options mode;
    deque<List> search_list;
    vector<string> dictionary;
    vector<bool> discovered;
    string output;
    int sel_word_i = 0;
    bool end_found = 0;
};

// later on in a function:
morph->search_list.push_back({ morph->dictionary.size() - 1, 0, 0, 0 });

2 Answers2

3

You can replace the last line with:

morph->search_list.emplace_back( morph->dictionary.size() - 1, 0, 0, 0 );

Thus the object is created not through brace initialization which does not allow narrowing conversion.

The narrowing conversion is from the return value of the call to size which returns std::size_t which is unsigned.

For why size() - 1 is not converted to a signed value see: C++ Implicit Conversion (Signed + Unsigned)

Amir Kirsh
  • 12,564
  • 41
  • 74
  • So that solved that error, but now I get the following: term does not evaluate to a function taking 1 argument – Francisco Skrobola Sep 16 '20 at 04:36
  • 1
    @FranciscoSkrobola - Read carefully. You need to change the member function being called from `push_back()` to `emplace_back()`. The two are not interchangeable when you're trying to construct and add and object. – Peter Sep 16 '20 at 04:57
  • I did change it but doing so caused the evaluation error – Francisco Skrobola Sep 16 '20 at 05:13
0

When and after you applied what Amir suggested, you may get an error saying something like, "this function does not take (3) arguments." To fix that you'll have to declare a constructor in the class, which you used for your vector, that takes that particular number of arguments. From what I understood when you replace push_back(); with emplace_back();the compiler thinks that you're trying to pass some variables to the constructor, which are the supposed arguments.

SmolBrain
  • 35
  • 6
  • 1
    Vector element type does not *need* to have a constructor in C++20 though. `emplace_back` uses placement-new in the form of `new(p) T(std::forward(args)...)` under the hood (except in exotic custom allocator cases), i.e. uses `()` brackets form (*direct initialization*) which didn't trigger aggregate initialization for aggregate types without suitable constructor before C++20, but now does due to [p0960](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0960r3.html). So, aggregates even without appropriate parametrized constructors can now be initialized within `emplace_back`. – YurkoFlisk Jul 27 '22 at 22:38