I have the below code. The first push_back fails, the second, with a constant string, works.
#include <vector>
#define MAX_LENGTH 10
struct bar
{
int barInt;
char barChar [MAX_LENGTH];
};
int main()
{
char fooString [MAX_LENGTH] = "Hello";
std::vector<bar> foo {};
foo.push_back( { 1 , fooString } ); // error: no matching function for call to ‘std::vector::push_back()’
foo.push_back( { 1 , "Hello" } ); // Works
}
Live demo - OnlineGDB
Sorry guys, but I don't get it really. What is the problem? A copy issue?
PS: std::string is in the whole context not an option.
In order to work, this line:
foo.push_back( { 1 , fooString } );
has to copy fooString into the barChar member of the new bar element.
But C strings which are actually [zero terminated] char arrays are non-copyable (see e.g. here), hence the error.
The other case (foo.push_back( { 1 , "Hello" } );) is OK because you can initialize a C string with a string literal.
One solution is to create a temporary bar object to push_back into the std::vector.
Alternatively as @user7860670 commented, you can avoid the temporary by pushing a zero initialized bar and setting the fields afterwards in the element inside the vector.
Note:
Unlike C arrays, std::array is copyable.
If you can use it instead of the C array it might be the simplest solution.
However - in order to initialize an std::array with a string you need to use uniform initialization syntax: std::array<char, MAX_LENGTH> fooString{"Hello"};.
A side note:
Instead of using a #define for your constant (MAX_LENGTH) you can consider to use a compile time constant (constexpr) which is considered more idiomatic.
See: Defining global constant in C++.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With