Cannot convert from 'const std::string [3]' to 'std::string'

Viewed 513

Here is my code:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

template<int N>
class Arguments
{
protected:
    string arguments[N];
public:
    Arguments(const string(&arg)[N]) : arguments{ arg } {}
    string operator[](const int &i) const { return arguments[i]; }
};

int main()
{
    string arr[3] = { "arg1", "arg2", "arg3" };
    Arguments<3> args(arr);

    cout << args[2];

    return 0;
}

This is the error i get:

Severity    Code    Description Project File    Line    Suppression State
Error   C2440   'initializing': cannot convert from 'const std::string [3]' to 'std::string'    
coursework_draft    C:\dev\coursework_draft\coursework_draft\coursework_draft.cpp   13  

What do i need to change?

3 Answers

Arrays are not copyable in C++. So this is never going to work

 Arguments(const string(&arg)[N]) : arguments{ arg } {}

You could use std::array<std::string, N> instead, or you could copy the array element by element in the body of the constructor.

This:

arguments{ arg }

is list-initialisation and means that the first element of arguments is initialised with arg. But the elements of arguments are std::string, which cannot be initialised with an array of strings.

Arrays are not copy-initialisable.

Classes however can be copy initialisable, and they can have array members. As such, you can use a class as a wrapper around an array that can be conveniently copied. The standard library has a template for such array wrapper. Its name is std::array.

Another option is to copy the array in the constructor body using std::copy or similar function.

You can use std::copy:

Arguments(const string(&arg)[N]) {
   std::copy(arg, arg + N, arguments); 
}

Here's a demo.

Related