0

The following code fails to compile.

#include <iostream>
#include <map>
#include <vector>

using namespace std;

class mc
{
    string s;
    public:
    mc(const std::string s) : s{s}{};
    // mc(const char * s) : s{s}{}; // Adding this line would make it work in both cases
};


int main()
{
    vector<mc> a = {"Hello", "there"};          //FAILS
    vector<mc> b = {mc("Hello"), mc("there")};  //WORKS
}

Depending on compiler error is

no matching function for call to  mc::mc(const char&)
note: candidate: ‘mc::mc(std::string)’
note: no known conversion for argument 1 from ‘const char’ to ‘std::string’

or

/usr/include/c++/11/bits/stl_uninitialized.h:138:72: error: static assertion failed: result type must be constructible from value type of input range

Why does this error happen? There is an implicit constructor from string. If instead of vector<mc> they were vector<string> it would work.

darmual
  • 229
  • 3
  • 7
  • What is `SatId` (from your error)? – erip Mar 03 '23 at 13:47
  • 3
    The compiler will only do 1 user-defined conversion in a conversion sequence. The code above requires 2 from `char const *` -> `std::string` -> `mc` – Richard Critten Mar 03 '23 at 13:52
  • Note that `mc a = "Hello";` also fails. – molbdnilo Mar 03 '23 at 13:54
  • [only one implicit user-defined conversion is allowed.](https://stackoverflow.com/a/867804/12002570) – Jason Mar 03 '23 at 14:01
  • This case is not about two implicit user-defined conversions, but about why the initialization of a `std::vector` from a range given by two iterators ([constructor #5](https://en.cppreference.com/w/cpp/container/vector/vector)) does not work. – j6t Mar 06 '23 at 09:54
  • @erip, fixed, should have been `mc` (had copied the error message before renaming to mc) – darmual Mar 06 '23 at 09:59
  • @j6t why do you think this is about constructor #5? Why would it be selected? – n. m. could be an AI Mar 08 '23 at 09:43
  • @n.m. (1) because two `const char*` pointers are passed to the constructor and (2) the error message clearly states that there is no conversion from a `const char` to `std::string`; a clear indication that a `const char*` was dereferenced to get a `const char`, which the implementation of the two-iterator constructor would do. – j6t Mar 08 '23 at 10:41
  • @j6t That's just one of many constructors that were not selected. There is no question why it wasn't selected, it simply doesn't match and is not meant to. – n. m. could be an AI Mar 08 '23 at 11:10
  • @n.m. Why do you think it doesn't match? Pointers are iterators, and when there's a constructor that takes a `char`, the previously failing initialization [can be compiled](https://godbolt.org/z/6YhxM95j1) (that the iterators aren't pointing into the same range is a different matter). – j6t Mar 08 '23 at 12:06
  • @j6t Because they are of a wrong type. There isn't a constructor that takes a `char`, why would one want that? – n. m. could be an AI Mar 08 '23 at 13:25
  • @n.m. Overload resolution does not ask whether a value pointed to by the iterator is convertible to the value type of the container. That this conversion is not possible is determined only long after the constructor has been selected as the best (or only) match. – j6t Mar 08 '23 at 14:08
  • @j6t libc++ and libstdc++ do it differently. libc++ does check that a value pointed to by the iterator is convertible to the value type of the container and rejects this constructor early. libstdc++ selects this constructor and static-asserts inside. The standard doesn't seem to tell what is right. – n. m. could be an AI Mar 08 '23 at 18:31
  • @n.m. [The restriction](http://www.eel.is/c++draft/sequence.reqmts#9) that elements must be emplace-constructible from the iterator range is listed as *precondition*, but not as *constraint*, so, compilers need not (must not?) exclude the constructor from overload resolution. – j6t Mar 08 '23 at 21:33
  • @j6t It isn't clear to me why the term "precondition" would imply that. Anyway it would matter if the chosen constructor is the best but not the only choice.Can it ever happen? – n. m. could be an AI Mar 08 '23 at 22:02

0 Answers0