Reputation: 4995
I am trying to fill a vector of strings with the elements in a list of pointers to C-style strings.
This works.
int main()
{
//typedef char cstr[];
using cstr = char[];
std::list<cstr*> lict(10);
std::vector<std::string> vec;
for(auto c:lict)
vec.push_back(*c);
return 0;
}
However when I try to assign to vec using the range of lict, I get an enormous error message.
int main()
{
using cstr = char[];
std::list<cstr*> lict(10);
std::vector<std::string> vec(lict.begin(), lict.end());
return 0;
}
Why can't I use this second method?
The error message is:
/usr/bin/../lib/c++/v1/memory:1681:31: error: no matching constructor for initialization of
'std::__1::basic_string<char>'
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/c++/v1/memory:1608:18: note: in instantiation of function template specialization
'std::__1::allocator<std::__1::basic_string<char> >::construct<std::__1::basic_string<char>, char (*&)[]>'
requested here
{__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
^
/usr/bin/../lib/c++/v1/memory:1492:14: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::basic_string<char> >
>::__construct<std::__1::basic_string<char>, char (*&)[]>' requested here
{__construct(__has_construct<allocator_type, pointer, _Args...>(),
^
/usr/bin/../lib/c++/v1/vector:933:25: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::basic_string<char> >
>::construct<std::__1::basic_string<char>, char (*&)[]>' requested here
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
^
/usr/bin/../lib/c++/v1/vector:1068:9: note: in instantiation of function template specialization
'std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> >
>::__construct_at_end<std::__1::__list_iterator<char (*)[], void *> >' requested here
__construct_at_end(__first, __last);
^
ex9_14b.cpp:9:29: note: in instantiation of function template specialization
'std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> >
>::vector<std::__1::__list_iterator<char (*)[], void *> >' requested here
std::vector<std::string> vec(lict.begin(),lict.end());
^
/usr/bin/../lib/c++/v1/string:1146:31: note: candidate constructor not viable: cannot convert argument of incomplete
type 'char (*)[]' to 'const_pointer' (aka 'const char *')
_LIBCPP_INLINE_VISIBILITY basic_string(const_pointer __s);
^
/usr/bin/../lib/c++/v1/string:1136:40: note: candidate constructor not viable: cannot convert argument of incomplete
type 'char (*)[]' to 'const allocator_type' (aka 'const std::__1::allocator<char>')
_LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a);
^
/usr/bin/../lib/c++/v1/string:1137:5: note: candidate constructor not viable: cannot convert argument of incomplete type
'char (*)[]' to 'const std::__1::basic_string<char>'
basic_string(const basic_string& __str);
^
/usr/bin/../lib/c++/v1/string:1141:5: note: candidate constructor not viable: cannot convert argument of incomplete type
'char (*)[]' to 'std::__1::basic_string<char>'
basic_string(basic_string&& __str)
^
/usr/bin/../lib/c++/v1/string:1167:5: note: candidate constructor not viable: cannot convert argument of incomplete type
'char (*)[]' to 'initializer_list<value_type>'
basic_string(initializer_list<value_type> __il);
^
/usr/bin/../lib/c++/v1/string:1161:9: note: candidate constructor template not viable: requires 2 arguments, but 1 was
provided
basic_string(_InputIterator __first, _InputIterator __last);
^
/usr/bin/../lib/c++/v1/string:1164:9: note: candidate constructor template not viable: requires 3 arguments, but 1 was
provided
basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
^
/usr/bin/../lib/c++/v1/string:1134:31: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
_LIBCPP_INLINE_VISIBILITY basic_string()
^
/usr/bin/../lib/c++/v1/string:1138:5: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
basic_string(const basic_string& __str, const allocator_type& __a);
^
/usr/bin/../lib/c++/v1/string:1144:5: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
basic_string(basic_string&& __str, const allocator_type& __a);
^
/usr/bin/../lib/c++/v1/string:1148:5: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
basic_string(const_pointer __s, const allocator_type& __a);
^
/usr/bin/../lib/c++/v1/string:1150:5: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
basic_string(const_pointer __s, size_type __n);
^
/usr/bin/../lib/c++/v1/string:1152:5: note: candidate constructor not viable: requires 3 arguments, but 1 was provided
basic_string(const_pointer __s, size_type __n, const allocator_type& __a);
^
/usr/bin/../lib/c++/v1/string:1154:5: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
basic_string(size_type __n, value_type __c);
^
/usr/bin/../lib/c++/v1/string:1156:5: note: candidate constructor not viable: requires 3 arguments, but 1 was provided
basic_string(size_type __n, value_type __c, const allocator_type& __a);
^
/usr/bin/../lib/c++/v1/string:1157:5: note: candidate constructor not viable: requires at least 2 arguments, but 1 was
provided
basic_string(const basic_string& __str, size_type __pos, size_type __n = npos,
^
/usr/bin/../lib/c++/v1/string:1169:5: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
basic_string(initializer_list<value_type> __il, const allocator_type& __a);
Upvotes: 1
Views: 2008
Reputation: 2192
candidate constructor not viable: cannot convert argument of incomplete type 'char (*)[]' to 'const_pointer' (aka 'const char *')
The value-type of your list is not convertible to std::string
.
try const char*
:
std::list<const char*> lict{"Hello", "World"};
std::vector<std::string> vec(lict.begin(), lict.end());
see here
Upvotes: 0
Reputation: 6985
Because the line:
std::vector<std::string> vec(lict.begin(), lict.end());
uses a constructor having the following prototype (see here):
template< class InputIt >
vector( InputIt first, InputIt last, const Allocator& alloc = Allocator() );
first
and last
are iterators in a container whose contained type must be the same as your container's, i.e. std::string
.
Upvotes: 0
Reputation: 153810
You create a list with 10 pointers to pointers to char
, i.e., you list elements are of type char**
but you want them to be of type char*
or char const*
. Note that fixing the type will result in a program with indefined behavior: the precondition on calling the std::string
constructor with a char const*
is that the pointer piints to a valid C string.
Upvotes: 1