0

I have a function that I want to be able to accept const vector<const string> but I also want the user to be able to pass vector<string> as well. I thought I could just make the function argument be a reference to const and that a non-const vector would still be accepted, but it's not. Here's an example:

void test(const vector<const string> &v)
{
    return;
}

int main( int argc, char *argv[] )
{
    vector<string> v;
    test(v);

    return 0;
}

The error I receive is:

error C2664: 'test' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'const std::vector<_Ty> &'


Why doesn't the example work and how do you suggest I make my function work so the user can pass const vector<const string> and vector<string>? Thanks

loop
  • 3,460
  • 5
  • 34
  • 57
  • 6
    They're not the same types and there is no plausible implicit conversion. Without a strong use-case for having a vector of `const string` I question the very design itself. Element-access and modification is already restricted due to the `const&` nature of the vector itself, so what exactly are you hoping you're *gaining* by making the element type `const string` in the first place. – WhozCraig Mar 20 '14 at 05:16
  • @WhozCraig I thought if I made my reference the most restrictive use case with const that cases without any const restrictions could just be converted to that. – loop Mar 20 '14 at 05:28
  • The container as `const&`, yes. But the types (thats all you're really doing when supplying template parameters; contriving a type) are *different* if the element types are different (and your are). I would be highly suspect if you can *not* do what you need with the appropriate const-ness afforded a simple `const std::vector&` function parameter. Only the `const` members are allowed, and only `const` element references and pointers and container iterators will likewise be allowed. – WhozCraig Mar 20 '14 at 05:40
  • 2
    Objects in a vector must be copyable and assignable (otherwise the behaviour is undefined), `vector` does not satisfy these requirements. – M.M Mar 20 '14 at 05:52
  • @Matt Does that mean one should never use `vector`? Aside from the above question I thought it would be safer in code. so that I would be less likely to cause an error by changing a string I really shouldn't. – loop Mar 20 '14 at 06:01
  • 1
    Yes, WhozCraig was a bit more diplomatic about it, but IMO you should never use `vector` . You are just causing undefined behaviour, not gaining any safety. If you are concerned about accidentally changing it, then make it private and access it through a const reference, or something. – M.M Mar 20 '14 at 06:04

1 Answers1

0

This post maybe can help you. However you can force your call in this (horrible) way

test(*reinterpret_cast<vector<const string>*>(&v));

that in some way also illustrates why it is not possible an automatic conversion. You could break container's rules:

vector<string> v = {"a", "b"};
vector<const string>& vc = v; //not allowed, of course
v[0].clear(); //<-- but also vc[0] is cleared
Community
  • 1
  • 1
Salvatore Avanzo
  • 2,656
  • 1
  • 21
  • 30