Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #87714 > unrolled thread

initial size of a std::vector of std::strings

Started byLynn McGuire <lynnmcguire5@gmail.com>
First post2022-12-06 23:42 -0600
Last post2022-12-08 01:44 -0600
Articles 20 on this page of 30 — 11 participants

Back to article view | Back to comp.lang.c++


Contents

  initial size of a std::vector of std::strings Lynn McGuire <lynnmcguire5@gmail.com> - 2022-12-06 23:42 -0600
    Re: initial size of a std::vector of std::strings James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-12-07 00:52 -0500
    Re: initial size of a std::vector of std::strings Bonita Montero <Bonita.Montero@gmail.com> - 2022-12-07 08:17 +0100
    Re: initial size of a std::vector of std::strings Öö Tiib <ootiib@hot.ee> - 2022-12-07 00:23 -0800
      Re: initial size of a std::vector of std::strings Juha Nieminen <nospam@thanks.invalid> - 2022-12-07 09:13 +0000
        Re: initial size of a std::vector of std::strings Öö Tiib <ootiib@hot.ee> - 2022-12-07 06:03 -0800
          Re: initial size of a std::vector of std::strings Bonita Montero <Bonita.Montero@gmail.com> - 2022-12-07 15:37 +0100
            Re: initial size of a std::vector of std::strings Öö Tiib <ootiib@hot.ee> - 2022-12-07 09:33 -0800
              Re: initial size of a std::vector of std::strings Bonita Montero <Bonita.Montero@gmail.com> - 2022-12-07 18:45 +0100
        Re: initial size of a std::vector of std::strings Paavo Helde <eesnimi@osa.pri.ee> - 2022-12-07 16:34 +0200
          Re: initial size of a std::vector of std::strings Bonita Montero <Bonita.Montero@gmail.com> - 2022-12-07 15:38 +0100
          Re: initial size of a std::vector of std::strings Juha Nieminen <nospam@thanks.invalid> - 2022-12-08 07:58 +0000
      Re: initial size of a std::vector of std::strings Lynn McGuire <lynnmcguire5@gmail.com> - 2022-12-07 16:28 -0600
        Re: initial size of a std::vector of std::strings Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-12-07 14:53 -0800
          Re: initial size of a std::vector of std::strings Lynn McGuire <lynnmcguire5@gmail.com> - 2022-12-07 16:56 -0600
          Re: initial size of a std::vector of std::strings Juha Nieminen <nospam@thanks.invalid> - 2022-12-08 08:03 +0000
    Re: initial size of a std::vector of std::strings "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-12-07 12:28 +0100
      Re: initial size of a std::vector of std::strings Lynn McGuire <lynnmcguire5@gmail.com> - 2022-12-07 14:54 -0600
        Re: initial size of a std::vector of std::strings "daniel...@gmail.com" <danielaparker@gmail.com> - 2022-12-07 13:16 -0800
        Re: initial size of a std::vector of std::strings "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-12-07 22:33 +0100
          Re: initial size of a std::vector of std::strings Bonita Montero <Bonita.Montero@gmail.com> - 2022-12-07 22:37 +0100
        Re: initial size of a std::vector of std::strings Michael S <already5chosen@yahoo.com> - 2022-12-07 13:34 -0800
          Re: initial size of a std::vector of std::strings Bo Persson <bo@bo-persson.se> - 2022-12-07 23:48 +0100
        Re: initial size of a std::vector of std::strings Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-12-07 13:49 -0800
          Re: initial size of a std::vector of std::strings Lynn McGuire <lynnmcguire5@gmail.com> - 2022-12-07 16:01 -0600
            Re: initial size of a std::vector of std::strings Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-12-07 14:47 -0800
              Re: initial size of a std::vector of std::strings Lynn McGuire <lynnmcguire5@gmail.com> - 2022-12-07 17:09 -0600
        Re: initial size of a std::vector of std::strings Bo Persson <bo@bo-persson.se> - 2022-12-07 23:45 +0100
          Re: initial size of a std::vector of std::strings Lynn McGuire <lynnmcguire5@gmail.com> - 2022-12-07 17:08 -0600
    Re: initial size of a std::vector of std::strings Lynn McGuire <lynnmcguire5@gmail.com> - 2022-12-08 01:44 -0600

Page 1 of 2  [1] 2  Next page →


#87714 — initial size of a std::vector of std::strings

FromLynn McGuire <lynnmcguire5@gmail.com>
Date2022-12-06 23:42 -0600
Subjectinitial size of a std::vector of std::strings
Message-ID<tmp947$g0jv$1@dont-email.me>
Is there a way to set the size of std::vector <std::string> formulas to 
max_ncp size ?

Something like "std::vector <std::string> formulas [max_ncp];"

Thanks,
Lynn

[toc] | [next] | [standalone]


#87715

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-12-07 00:52 -0500
Message-ID<tmp9md$fvil$1@dont-email.me>
In reply to#87714
On 12/7/22 00:42, Lynn McGuire wrote:
> Is there a way to set the size of std::vector <std::string> formulas to 
> max_ncp size ?
> 
> Something like "std::vector <std::string> formulas [max_ncp];"
> 
> Thanks,
> Lynn

23.2.6.1:
explicit vector(size_type n);
5 Effects: Constructs a vector with n default constructed elements.
6 Requires: T shall be DefaultConstructible.
7 Complexity: Linear in n.

[toc] | [prev] | [next] | [standalone]


#87716

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-12-07 08:17 +0100
Message-ID<tmpeln$gdbo$1@dont-email.me>
In reply to#87714
Am 07.12.2022 um 06:42 schrieb Lynn McGuire:

> Is there a way to set the size of std::vector <std::string> formulas to 
> max_ncp size ?
> Something like "std::vector <std::string> formulas [max_ncp];"
> Thanks,
> Lynn

If you want to seqentially fill up the vector with your data up to the
size you allocated before declare an empty-sized vector<string>, do a
vec.reserve( max_ncp ) and have an according number of emplace_back
to that vector afterwards:

	vector<string> vStr;
	vStr.reserve( max_ncp );
	for( size_t i = 0; i != max_ncp; ++i )
		vStr.emplace_back( ... );

[toc] | [prev] | [next] | [standalone]


#87717

FromÖö Tiib <ootiib@hot.ee>
Date2022-12-07 00:23 -0800
Message-ID<6762abc6-85ac-4173-b807-aa27c36a04bcn@googlegroups.com>
In reply to#87714
On Wednesday, 7 December 2022 at 07:42:49 UTC+2, Lynn McGuire wrote:
> Is there a way to set the size of std::vector <std::string> formulas to 
> max_ncp size ? 
> 
> Something like "std::vector <std::string> formulas [max_ncp];" 

When that max_ncp is compile-time known immutable value then 
std::array<std::string, max_ncp> can be what you want.

Maybe worth to note that I've seen reserve(n) of std::vector overused
in practice as bad pessimization. Vector is typically designed so that 
we get log(max) allocations and max times element copies because
of vector just growing freely during its life-time. That can be turned into
way worse by someone micromanaging it.

[toc] | [prev] | [next] | [standalone]


#87719

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-12-07 09:13 +0000
Message-ID<tmplf6$3sr$1@gioia.aioe.org>
In reply to#87717
Öö Tiib <ootiib@hot.ee> wrote:
> Maybe worth to note that I've seen reserve(n) of std::vector overused
> in practice as bad pessimization. Vector is typically designed so that 
> we get log(max) allocations and max times element copies because
> of vector just growing freely during its life-time. That can be turned into
> way worse by someone micromanaging it.

The typical std::vector implementation doubles its capacity every time it
needs to grow.

Now consider what happens if you are adding, say, at least a thousand
elements to a vector (using push_back() or emplace_back()): It will do
ten reallocations pretty quickly in succession, every time it has to
double its capacity. While the frequency at which it's doing these
reallocations is decrementing exponentially, at the beginning they
are very frequent, and there's literally no advantage in doing them.

If you know that you will be adding at least a thousand or so
elements, doing an initial reserve(1024) will remove *all* of those
useless initial ten reallocations.

Avoiding the useless reallocations is not just a question of speed,
but also of avoiding memory fragmentation. The less dynamic memory
allocations you do, the better (in terms of both).

[toc] | [prev] | [next] | [standalone]


#87721

FromÖö Tiib <ootiib@hot.ee>
Date2022-12-07 06:03 -0800
Message-ID<64dbcaba-4dc7-4aef-b1b1-11fd46f96a89n@googlegroups.com>
In reply to#87719
On Wednesday, 7 December 2022 at 11:13:29 UTC+2, Juha Nieminen wrote:
> Öö Tiib <oot...@hot.ee> wrote: 
> > Maybe worth to note that I've seen reserve(n) of std::vector overused 
> > in practice as bad pessimization. Vector is typically designed so that 
> > we get log(max) allocations and max times element copies because 
> > of vector just growing freely during its life-time. That can be turned into 
> > way worse by someone micromanaging it.
>
> The typical std::vector implementation doubles its capacity every time it 
> needs to grow. 
> 
> Now consider what happens if you are adding, say, at least a thousand 
> elements to a vector (using push_back() or emplace_back()): It will do 
> ten reallocations pretty quickly in succession, every time it has to 
> double its capacity. While the frequency at which it's doing these 
> reallocations is decrementing exponentially, at the beginning they 
> are very frequent, and there's literally no advantage in doing them. 
> 
> If you know that you will be adding at least a thousand or so 
> elements, doing an initial reserve(1024) will remove *all* of those 
> useless initial ten reallocations. 

That is is all trivially true. One reserve() call is not "micromanaging" so
you missed my point. What I described can be achieved by calling
reserve more than once for example in 1024 element steps for vector
that grows to million elements. Result is that you get like 50 times 
more allocations and element copies. It does replace first 10 
allocations with one but next 10 with 1000.   

> Avoiding the useless reallocations is not just a question of speed, 
> but also of avoiding memory fragmentation. The less dynamic memory 
> allocations you do, the better (in terms of both).

Yes, the misused reserve calls can also fragment the memory far worse
as the less dynamic memory allocations you do, the better. 

[toc] | [prev] | [next] | [standalone]


#87723

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-12-07 15:37 +0100
Message-ID<tmq8ej$ivl3$1@dont-email.me>
In reply to#87721
Am 07.12.2022 um 15:03 schrieb Öö Tiib:

> That is is all trivially true. One reserve() call is not "micromanaging"
> so you missed my point. What I described can be achieved by calling
> reserve more than once for example in 1024 element steps for vector
> that grows to million elements. Result is that you get like 50 times
> more allocations and element copies. It does replace first 10
> allocations with one but next 10 with 1000.


For each append where the capacity grows the vector's capacity is
doubled with libstdc++ and libc++. With MSVC the capacity grows in
50%-increments. So the number of resizes actually isn't so huge.
Java does it the same way and stores the data of an ArrayList also
in a normal array that grows by 100% if the capacity is exhausted.

> Yes, the misused reserve calls can also fragment the memory ...

With moderen allocators like mimalloc, jemalloc and tcmalloc external
fragementation isn't actually an issue since there's no external frag-
mentation up to a size of two pages (but an average internal fragmen-
tation of 25%) and beyond that the memory blocks grow in page incre-
ments and each page can easily be deallocated so that external frag-
mentation doesn't hurt much.


[toc] | [prev] | [next] | [standalone]


#87727

FromÖö Tiib <ootiib@hot.ee>
Date2022-12-07 09:33 -0800
Message-ID<99fc9a54-2725-42fd-990a-2685bf55316fn@googlegroups.com>
In reply to#87723
On Wednesday, 7 December 2022 at 16:37:25 UTC+2, Bonita Montero wrote:
> Am 07.12.2022 um 15:03 schrieb Öö Tiib: 
> 
> > That is is all trivially true. One reserve() call is not "micromanaging" 
> > so you missed my point. What I described can be achieved by calling 
> > reserve more than once for example in 1024 element steps for vector 
> > that grows to million elements. Result is that you get like 50 times 
> > more allocations and element copies. It does replace first 10 
> > allocations with one but next 10 with 1000.
> For each append where the capacity grows the vector's capacity is 
> doubled with libstdc++ and libc++. With MSVC the capacity grows in 
> 50%-increments. So the number of resizes actually isn't so huge.

Yes that was my point that the logarithm of base 2 of million is 
about 20 and logarithm of base 1.5 of million is about 28. Neither
is large number and so default behaviour of mainstream standard
library vector implementations is reasonable. 

Application programmer is in my experience rather capable of
being unreasonable and micromanaging and reserving linearly.
So when suggesting manual reserve() then it is always worth to
warn that it is double edged sword not some kind of magic tool.

One example of common naive usage of reserve() is instead of
plain insert() of range (that grows exponentially if needed) is
checking how lot more storage is needed, reserving for it and
then adding the elements. Other tool that is on about 9/10
cases pessimally used is shrink_to_fit().

[toc] | [prev] | [next] | [standalone]


#87728

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-12-07 18:45 +0100
Message-ID<tmqjfb$k0mf$1@dont-email.me>
In reply to#87727
Am 07.12.2022 um 18:33 schrieb Öö Tiib:

> Application programmer is in my experience rather capable of
> being unreasonable and micromanaging and reserving linearly.
> So when suggesting manual reserve() then it is always worth to
> warn that it is double edged sword not some kind of magic tool.

reserve isn't hard to use and it is used if you know the number
of inserted items. So I don't believe that a misuse of reserve()
is common.

> One example of common naive usage of reserve() is instead of
> plain insert() of range (that grows exponentially if needed) is
> checking how lot more storage is needed, reserving for it and
> then adding the elements. ...

That may sense if you have a really large vector that isn't backed
by a memory pool but allocated directly from the kernel and given
back to the kernel when being freed becaus of the size of the allo-
cation. If that happens the allocated pages aren't actually commit-
ted until you touch them and on some systems they're even not sub-
tracted from swap on allocation (overcommit).

[toc] | [prev] | [next] | [standalone]


#87722

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-12-07 16:34 +0200
Message-ID<tmq88o$iulk$1@dont-email.me>
In reply to#87719
07.12.2022 11:13 Juha Nieminen kirjutas:
> Öö Tiib <ootiib@hot.ee> wrote:
>> Maybe worth to note that I've seen reserve(n) of std::vector overused
>> in practice as bad pessimization. Vector is typically designed so that
>> we get log(max) allocations and max times element copies because
>> of vector just growing freely during its life-time. That can be turned into
>> way worse by someone micromanaging it.
> 
> The typical std::vector implementation doubles its capacity every time it
> needs to grow.

Not any more. Nowadays a factor like 1.5 is more popular, meaning 
something like 18 allocations for 1000 push_back()-s. This is from MSVC++19:

	std::vector<int, my_allocator<int>> v;
	for (int i = 0; i < 1000; ++i) {
		v.push_back(i);
	}


Allocating 1 elements
Allocating 1 elements
Allocating 2 elements
Allocating 3 elements
Allocating 4 elements
Allocating 6 elements
Allocating 9 elements
Allocating 13 elements
Allocating 19 elements
Allocating 28 elements
Allocating 42 elements
Allocating 63 elements
Allocating 94 elements
Allocating 141 elements
Allocating 211 elements
Allocating 316 elements
Allocating 474 elements
Allocating 711 elements
Allocating 1066 elements

[toc] | [prev] | [next] | [standalone]


#87724

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-12-07 15:38 +0100
Message-ID<tmq8gn$ivl3$2@dont-email.me>
In reply to#87722
Am 07.12.2022 um 15:34 schrieb Paavo Helde:

> Not any more. Nowadays a factor like 1.5 is more popular, ...

Only MSVC uses 50% increments to satisfy the amortized constant
overhead constraint while inserting. libstdc++ and libc++ use a
100% increment.

[toc] | [prev] | [next] | [standalone]


#87748

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-12-08 07:58 +0000
Message-ID<tms5ep$1u83$1@gioia.aioe.org>
In reply to#87722
Paavo Helde <eesnimi@osa.pri.ee> wrote:
> 07.12.2022 11:13 Juha Nieminen kirjutas:
>> Öö Tiib <ootiib@hot.ee> wrote:
>>> Maybe worth to note that I've seen reserve(n) of std::vector overused
>>> in practice as bad pessimization. Vector is typically designed so that
>>> we get log(max) allocations and max times element copies because
>>> of vector just growing freely during its life-time. That can be turned into
>>> way worse by someone micromanaging it.
>> 
>> The typical std::vector implementation doubles its capacity every time it
>> needs to grow.
> 
> Not any more. Nowadays a factor like 1.5 is more popular, meaning 
> something like 18 allocations for 1000 push_back()-s.

The more the reason to do the initial reserve if you know the number of
elements that will be added.

> This is from MSVC++19:

I believe both libstdc++ (used by default by gcc) and libc++ (used by
default by clang) double the size. I doubt they are going to change
any time soon.

Obviously there are advantages and disadvantages in each percentage.

[toc] | [prev] | [next] | [standalone]


#87738

FromLynn McGuire <lynnmcguire5@gmail.com>
Date2022-12-07 16:28 -0600
Message-ID<tmr41s$lk9a$1@dont-email.me>
In reply to#87717
On 12/7/2022 2:23 AM, Öö Tiib wrote:
> On Wednesday, 7 December 2022 at 07:42:49 UTC+2, Lynn McGuire wrote:
>> Is there a way to set the size of std::vector <std::string> formulas to
>> max_ncp size ?
>>
>> Something like "std::vector <std::string> formulas [max_ncp];"
> 
> When that max_ncp is compile-time known immutable value then
> std::array<std::string, max_ncp> can be what you want.
> 
> Maybe worth to note that I've seen reserve(n) of std::vector overused
> in practice as bad pessimization. Vector is typically designed so that
> we get log(max) allocations and max times element copies because
> of vector just growing freely during its life-time. That can be turned into
> way worse by someone micromanaging it.

Now I am wondering if I should be using std::array instead of std::vector.

Thanks,
Lynn

[toc] | [prev] | [next] | [standalone]


#87742

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2022-12-07 14:53 -0800
Message-ID<875yem6d1o.fsf@nosuchdomain.example.com>
In reply to#87738
Lynn McGuire <lynnmcguire5@gmail.com> writes:
> On 12/7/2022 2:23 AM, Öö Tiib wrote:
>> On Wednesday, 7 December 2022 at 07:42:49 UTC+2, Lynn McGuire wrote:
>>> Is there a way to set the size of std::vector <std::string> formulas to
>>> max_ncp size ?
>>>
>>> Something like "std::vector <std::string> formulas [max_ncp];"
>> When that max_ncp is compile-time known immutable value then
>> std::array<std::string, max_ncp> can be what you want.
>> Maybe worth to note that I've seen reserve(n) of std::vector
>> overused
>> in practice as bad pessimization. Vector is typically designed so that
>> we get log(max) allocations and max times element copies because
>> of vector just growing freely during its life-time. That can be turned into
>> way worse by someone micromanaging it.
>
> Now I am wondering if I should be using std::array instead of std::vector.

Only if the size of the vector will never change after it's created (I
don't think you mentioned that).  And in that case, you could use either
a std::array of std::string:

    std::array<std::string, max_ncp> formulas;

or a plain array of std::string:

    std::vector formulas[max_ncp];

Both require max_ncp to be a constant expression.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for XCOM Labs
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#87743

FromLynn McGuire <lynnmcguire5@gmail.com>
Date2022-12-07 16:56 -0600
Message-ID<tmr5md$lk9a$2@dont-email.me>
In reply to#87742
On 12/7/2022 4:53 PM, Keith Thompson wrote:
> Lynn McGuire <lynnmcguire5@gmail.com> writes:
>> On 12/7/2022 2:23 AM, Öö Tiib wrote:
>>> On Wednesday, 7 December 2022 at 07:42:49 UTC+2, Lynn McGuire wrote:
>>>> Is there a way to set the size of std::vector <std::string> formulas to
>>>> max_ncp size ?
>>>>
>>>> Something like "std::vector <std::string> formulas [max_ncp];"
>>> When that max_ncp is compile-time known immutable value then
>>> std::array<std::string, max_ncp> can be what you want.
>>> Maybe worth to note that I've seen reserve(n) of std::vector
>>> overused
>>> in practice as bad pessimization. Vector is typically designed so that
>>> we get log(max) allocations and max times element copies because
>>> of vector just growing freely during its life-time. That can be turned into
>>> way worse by someone micromanaging it.
>>
>> Now I am wondering if I should be using std::array instead of std::vector.
> 
> Only if the size of the vector will never change after it's created (I
> don't think you mentioned that).  And in that case, you could use either
> a std::array of std::string:
> 
>      std::array<std::string, max_ncp> formulas;
> 
> or a plain array of std::string:
> 
>      std::vector formulas[max_ncp];
> 
> Both require max_ncp to be a constant expression.

Yup, either would work well for me.  max_ncp is a const int that only 
changes at a far future recompile time.
	const int max_ncp = 1000;

Thanks,
Lynn

[toc] | [prev] | [next] | [standalone]


#87749

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-12-08 08:03 +0000
Message-ID<tms5nm$1p3$1@gioia.aioe.org>
In reply to#87742
Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>> Now I am wondering if I should be using std::array instead of std::vector.
> 
> Only if the size of the vector will never change after it's created

Also, you need to know the size at compile time, which isn't a trivial
restriction.

If the size is determined at compile time, std::array is *almost* always
a more efficient solution than std::vector.

*Almost* always. There are situations where std::vector can actually be
the more efficient solution. One such situation is if you find the need
to move the vector around a lot (ie. with its move constructor/assignment
operator).

Also, extremely large arrays (megabytes or more) might be better allocated
with std::vector, as a C-style array / std::array may start exhibiting some
problems when it becomes too large. (Heaven forbid you create one on the
stack!)

[toc] | [prev] | [next] | [standalone]


#87720

From"Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Date2022-12-07 12:28 +0100
Message-ID<tmptcb$hm5s$1@dont-email.me>
In reply to#87714
On 7 Dec 2022 06:42, Lynn McGuire wrote:
> Is there a way to set the size of std::vector <std::string> formulas to 
> max_ncp size ?
> 
> Something like "std::vector <std::string> formulas [max_ncp];"

The most reasonable interpretation to me is that you're asking how to 
set the initial /capacity/ of the vector in the declaration, to avoid an 
explicit .reserve() invocation as a separate following statement.

Presumably because you declare such vectors in many places.

To do that you can to wrap the vector, either via a factory function or 
via a simple class, like

     struct Capacity{ int value; };

     struct Fast_stringvec:
         public vector<string>
     {
         template< class... Args >
         Fast_stringvec( const Capacity capacity, Args&&... args ):
             vector<string>( forward<Args>( args )... )
         {
             reserve( capacity.value );
         }
     };

Then do e.g.

     auto formulas = Fast_stringvec( Capacity( max_ncp ) );

... where I believe the use of `auto` helps avoid the Most Vexing Parse. ;-)

If `max_ncp` is a constant you can add a constructor that uses that by 
default.

---

A not so reasonable interpretation is that you're asking how to make the 
vector contain `max_ncp` strings initially, for which you can just do

     vector<string> formulas( max_ncp, ""s );

---

Crossing the line to perhaps unreasonable interpretation is that you're 
asking how you can make it so that when you add a new to string to the 
vector, the new string item will guaranteed be of size `max_ncp`.

For that you need to make the item type one that holds a `string` of 
exactly that size.

It would probably be necessary to take control of copying to such items, 
to avoid inadvertent size changes.


- Alf

[toc] | [prev] | [next] | [standalone]


#87731

FromLynn McGuire <lynnmcguire5@gmail.com>
Date2022-12-07 14:54 -0600
Message-ID<tmquhd$kuud$1@dont-email.me>
In reply to#87720
On 12/7/2022 5:28 AM, Alf P. Steinbach wrote:
> On 7 Dec 2022 06:42, Lynn McGuire wrote:
>> Is there a way to set the size of std::vector <std::string> formulas 
>> to max_ncp size ?
>>
>> Something like "std::vector <std::string> formulas [max_ncp];"
> 
> The most reasonable interpretation to me is that you're asking how to 
> set the initial /capacity/ of the vector in the declaration, to avoid an 
> explicit .reserve() invocation as a separate following statement.
> 
> Presumably because you declare such vectors in many places.
> 
> To do that you can to wrap the vector, either via a factory function or 
> via a simple class, like
> 
>      struct Capacity{ int value; };
> 
>      struct Fast_stringvec:
>          public vector<string>
>      {
>          template< class... Args >
>          Fast_stringvec( const Capacity capacity, Args&&... args ):
>              vector<string>( forward<Args>( args )... )
>          {
>              reserve( capacity.value );
>          }
>      };
> 
> Then do e.g.
> 
>      auto formulas = Fast_stringvec( Capacity( max_ncp ) );
> 
> ... where I believe the use of `auto` helps avoid the Most Vexing Parse. 
> ;-)
> 
> If `max_ncp` is a constant you can add a constructor that uses that by 
> default.
> 
> ---
> 
> A not so reasonable interpretation is that you're asking how to make the 
> vector contain `max_ncp` strings initially, for which you can just do
> 
>      vector<string> formulas( max_ncp, ""s );
> 
> ---
> 
> Crossing the line to perhaps unreasonable interpretation is that you're 
> asking how you can make it so that when you add a new to string to the 
> vector, the new string item will guaranteed be of size `max_ncp`.
> 
> For that you need to make the item type one that holds a `string` of 
> exactly that size.
> 
> It would probably be necessary to take control of copying to such items, 
> to avoid inadvertent size changes.
> 
> 
> - Alf

I am trying to declare a vector with max_ncp strings in a struct.
struct component_data {
	std::vector <std::string> component_names [max_ncp];
	doublereal heatoffusionatmeltingpoint [max_ncp];
	doublereal meltingpointtemperature [max_ncp];
	doublereal sublimationtemperature [max_ncp];
	doublereal triplepointtemperature [max_ncp];
	doublereal triplepointpressure [max_ncp];
};

Visual Studio 2015 does not like
    	std::vector <std::string> component_names (max_ncp);
or
	std::vector <std::string> component_names (max_ncp, "");

But it does like
	std::vector <std::string> component_names [max_ncp];
But it does not work.

Thanks,
Lynn

[toc] | [prev] | [next] | [standalone]


#87732

From"daniel...@gmail.com" <danielaparker@gmail.com>
Date2022-12-07 13:16 -0800
Message-ID<526baf95-43b4-4ddf-8474-e01766324cd7n@googlegroups.com>
In reply to#87731
On Wednesday, December 7, 2022 at 3:54:23 PM UTC-5, Lynn McGuire wrote:

> I am trying to declare a vector with max_ncp strings in a struct. 
> struct component_data { 
> std::vector <std::string> component_names [max_ncp]; 
> doublereal heatoffusionatmeltingpoint [max_ncp]; 
> doublereal meltingpointtemperature [max_ncp]; 
> doublereal sublimationtemperature [max_ncp]; 
> doublereal triplepointtemperature [max_ncp]; 
> doublereal triplepointpressure [max_ncp]; 
> }; 
> 
> Visual Studio 2015 does not like 
> std::vector <std::string> component_names (max_ncp); 
> or 
> std::vector <std::string> component_names (max_ncp, ""); 
> 
> But it does like 
> std::vector <std::string> component_names [max_ncp]; 
> But it does not work. 
> 

Is this what you want?

struct component_data {
    const std::size_t max_ncp = 10;

    std::vector <std::string> component_names;

    component_data()
        : component_names(max_ncp)
    {}
};

VS 2015 is fine with that.

Daniel

[toc] | [prev] | [next] | [standalone]


#87733

From"Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Date2022-12-07 22:33 +0100
Message-ID<tmr0ri$l5qt$1@dont-email.me>
In reply to#87731
On 7 Dec 2022 21:54, Lynn McGuire wrote:
> 
> I am trying to declare a vector with max_ncp strings in a struct.
> struct component_data {
>      std::vector <std::string> component_names [max_ncp];
>      doublereal heatoffusionatmeltingpoint [max_ncp];
>      doublereal meltingpointtemperature [max_ncp];
>      doublereal sublimationtemperature [max_ncp];
>      doublereal triplepointtemperature [max_ncp];
>      doublereal triplepointpressure [max_ncp];
> };
> 
> Visual Studio 2015 does not like
>         std::vector <std::string> component_names (max_ncp);
> or
>      std::vector <std::string> component_names (max_ncp, "");
> 
> But it does like
>      std::vector <std::string> component_names [max_ncp];
> But it does not work.

It seems to me that what you're trying to do is simply

     struct Components_data
     {
         int             n_components;
         std::string     name [max_ncp];
         double          heat_of_fusion_at_melting_point [max_ncp];
         double          melting_point_temperature [max_ncp];
         double          sublimation_temperature [max_ncp];
         double          triple_point_temperature [max_ncp];
         double          triple_point_pressure [max_ncp];
     };

But with `std::string` involved this is not a memory layout of a Fortran 
structure.

So, do consider whether this can serve your requirements instead:

     struct Component
     {
         std::string     name;
         double          heat_of_fusion_at_melting_point;
         double          melting_point_temperature;
         double          sublimation_temperature;
         double          triple_point_temperature;
         double          triple_point_pressure;
     };

     using Components_data = std::vector<Component>;

Depending on the processing you do this might be slower or faster, needs 
measuring if that's important.

It /is/ however IMO very likely much more convenient and easy to use 
correctly.

- Alf

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c++


csiph-web