0

Here's what i tried to do: (with comparison to std::vector<int>)

char s = 4;
std::vector<int> i;
std::vector<char> c;

i.insert(i.end(),{s+1,s+2,s+3}); // no warnings
c.insert(c.end(),{s+1,s+2,s+3}); // narrowing conversions of {s+1,s+2,s+3} from ints to chars

I know i can cast, but that gets ugly quickly. (especially with more arguments)

c.insert(c.end(),{(char)(s+1),(char)(s+2),(char)(s+3),(char)(s+4),(char)(s+5),(char)(s+6)});

Do we have to live with this? Or is there a better way?

Puddle
  • 2,993
  • 1
  • 19
  • 32

2 Answers2

0

Narrowing conversion in an initializer_list is a problem. See the answers to warning: narrowing conversion C++11.

You can use a helper function to get around the problem.

namespace MyApp
{
   char next(char c, int n) { return c+n; }
}

and use it as

c.insert(c.end(), {MyApp::next(s, 1), MyApp::next(s, 2), MyApp::next(s, 3)});
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • interesting, but a simpler way would be `char ch(char c){return c;}` and `{ch(s+1),ch(s+2),ch(s+3)}` – Puddle Feb 04 '20 at 19:51
  • 1
    @Puddle, I would advise against that. Use of macros to capture such functions is not encouraged any more. – R Sahu Feb 04 '20 at 20:01
  • it beats `{MyApp::next(s, 1), MyApp::next(s, 2), MyApp::next(s, 3)}` :} – Puddle Feb 04 '20 at 20:14
  • @Puddle, it depends on your point of view. I was trying to use a name similar to [`std::next`](https://en.cppreference.com/w/cpp/iterator/next) – R Sahu Feb 04 '20 at 20:42
  • hi again. just wondering why it's "not encouraged"? have you got any sources also? cause at the end of the day it's just a macro like any other. it's no different than if i just cast all the arguments myself. what could possibly be bad about it? – Puddle Feb 05 '20 at 14:44
  • The most compelling reason to avoid using macros is that it's very hard to debug anything that is defined using macros. – R Sahu Feb 06 '20 at 04:57
  • wait, are you saying don't EVER use macros? – Puddle Feb 06 '20 at 15:30
  • @Puddle, no. it's discouraged. If you can use an inline function instead of a macro, it's better to use an inline function. – R Sahu Feb 06 '20 at 15:44
  • ok, that makes sense. do you know any cases where macro functions are useful? – Puddle Feb 07 '20 at 20:47
  • @Puddle, Macros, in combination with templates and inline functions, are useful in reducing the need to manually type repetitive code. The loss in debugging capability is justified by the reduced amount of code. I strive to minimize use of macros but I find it hard to completely eliminate it. – R Sahu Feb 07 '20 at 20:55
0

If your list is regular, you could use a loop instead like

for (int i = 1; i <= 3; ++1)
{
    c.insert(c.end(), s + i);
}

If it s not regular, you could build a std::initializer_list, and then use insert's range overload to insert into the vector like

{
    auto elems  = {s+1,s+2,s+3};
    c.insert(c.end(), elems.begin(), elems.end());
}
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • wouldn't both those be slower? 1. the overhead of inserting. 2. converting a initializer_list to chars (and wasting 4x more memory) – Puddle Feb 04 '20 at 19:57
  • @Puddle It's possible. No real way to know without benchmarking it. option 2 is probably the faster of the two options. I also put option 2 in a scope so that `elems` is "released" and there is no wasted memory. – NathanOliver Feb 04 '20 at 20:01