octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: error: no matching constructor for initialization of 'string_vector'


From: Carnë Draug
Subject: Re: error: no matching constructor for initialization of 'string_vector'
Date: Fri, 26 Aug 2016 18:04:39 +0100

On 26 August 2016 at 02:40, Mike Miller <address@hidden> wrote:
> On Thu, Aug 25, 2016 at 20:43:19 -0400, Ben Abbott wrote:
>> On Aug 25, 2016, at 9:01 AM, Carnë Draug <address@hidden> wrote:
>> >
>> > In the change that's causing issues for clang, the argument is a
>> > std::set<std::string> so I would expect it to use the templated
>> > constructor for String_Container<std::string>.
>>
>> If I’m following … might clang require an explicit constructor for 
>> std::set<std::string>?
>
> I can reproduce this build error on Debian with clang 3.7 / libc++ 3.7.
>
> The specific constructor that should work but doesn't fails with the
> following error:
>
>   ../liboctave/util/str-vec.h:131:16: note: candidate template ignored: 
> substitution failure [with String_Container = set]: too few template 
> arguments for class template 'set'
>   string_vector::string_vector (const String_Container<std::string>& lst)
>                  ^                    ~~~~~~~~~~~~~~~~
>
> This appears to be the following issue filed with the C++ working group:
>
>   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2057
>
> And the attached patch resolves the default template argument resolution
> problem and the build finishes successfully for me. Feel free to refine
> however you like.
>

I have actually been having issues with this solution in other places and
have some alternative ideas but was thinking of delaying it until 4.4.

The problem is that the current solution only works for container
templates, and the first argument needs to be std::string.  It won't
work for a non-template class or a subclass, even if they meet the
requirements for Container.

The right way to do it would be to template
this without any variadic template.  I have tried that but then
we have issues because an unsigned int will match the template
constructor instead of our constructor with octave_idx_type.
This does happen, we have things like:

    std::map<std::string, std::string> m = ...;
    string_vector names (m.size ());

That can be fixed by casting to octave_idx_type but it would still break
backwards compatibility.  Also, maybe we already have enough single
argument constructors?

An alternative is to replace it with a constructor that accepts iterators
which is what the STL does:

    template <typename InputIt>
    string_vector (InputIt first, InputIt last);

but I think our user cases are always about copying all of the elements
in the container and the whole point of this is convenience.  Now I'm
thinking that this whole copying from one container to another is not
ideal, what we should be doing instead is avoiding this in the first place
and have better support for any container type.

Having better support for any container to avoid excessive copying is
a longer term project though.  But we could still add the range container
and start deprecating the container conversion constructor.

Carnë



reply via email to

[Prev in Thread] Current Thread [Next in Thread]