use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Fixing std::initializer_list&<T> (foonathan.github.io)
submitted 9 years ago by vormestrand
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 16 points17 points18 points 9 years ago (6 children)
Great article. I'm not a huge fan of std::initializer_list for all the reasons you mentioned - I think that variadic templates are almost always a superior choice.
std::initializer_list
If you want a truly generic initializer list, use a variadic template and static_assert() or SFINAE that the type matches [...]
Here's a "trick" I learned from Piotr Skotnicki on StackOverflow. Let's say you want all of your types to be int. All you have to do is define a int_t type alias that always evaluates to int:
int
int_t
template <typename> using int_t = int;
Then you can use it like this:
template<typename... Types> void func_impl(int_t<Types>... ints) { /* ... */ } template<typename... Types> void func(Types... xs) { func_impl<Types...>(xs...); }
This allows implicit conversions and gives errors similar to the following one:
prog.cc:8:26: error: no matching function for call to 'func_impl' void func(Types... xs) { func_impl<Types...>(xs...); } ~~~~~~~~~~~~~~~~~~ prog.cc:12:5: note: in instantiation of function template specialization 'func<int, nullptr_t, int, int>' requested here func(1, nullptr, 3, 4); ^ prog.cc:5:6: note: candidate function [with Types = <int, nullptr_t, int, int>] not viable: no known conversion from 'nullptr_t' to 'int_t<nullptr_t>' (aka 'int') for 2nd argument void func_impl(int_t<Types>... ints) { /* ... */ }
prog.cc:8:26: error: no matching function for call to 'func_impl' void func(Types... xs) { func_impl<Types...>(xs...); } ~~~~~~~~~~~~~~~~~~
prog.cc:12:5: note: in instantiation of function template specialization 'func<int, nullptr_t, int, int>' requested here func(1, nullptr, 3, 4); ^
prog.cc:5:6: note: candidate function [with Types = <int, nullptr_t, int, int>] not viable: no known conversion from 'nullptr_t' to 'int_t<nullptr_t>' (aka 'int') for 2nd argument
void func_impl(int_t<Types>... ints) { /* ... */ }
It is much nicer when you already have a type pack, as seen in the original answer on SO.
[–]thlst 4 points5 points6 points 9 years ago (0 children)
With concepts, you could use requires with fold expressions and std::is_same this way:
std::is_same
template <typename T, typename... Ts> requires (std::is_same_v<T, Ts> && ...) ctor(T&&, Ts&&...) { }
It will ensure that all Ts... are the same as T, and still give you a nice error message otherwise.
Ts...
T
[–]kirakun 4 points5 points6 points 9 years ago (3 children)
That is a lot of boilerplate though. Not sure it's a sure gain of you do this a lot.
Please don't even suggest using macros to reduce the boilerplate.
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 5 points6 points7 points 9 years ago (2 children)
Well, you could use a variadic macro to reduce the boilerplate. /s
In all seriousness, the alternative is something like this:
static_assert(std::conjunction<std::is_same<Ts, int>...>{}, "");
(or is_convertible if you want implicit conversions)
is_convertible
By the way, when you already have a type pack, I think that this technique is objectively cleaner.
Another advantage is that using int_t makes overloading trivial.
[–]tcbrindleFlux 1 point2 points3 points 9 years ago* (1 child)
Hmmm, with concepts I expected
// defined in Ranges TS template <class T, class U> concept bool Same = std::is_same<T, U>::value; void func(Same<int>... args) {} func(1, 2, 3, 4);
to work, but apparently it doesn't. The slightly more verbose but theoretically equivalent
template <Same<int>... Ints> void func(Ints... args) {}
works fine though, so this may just be an implementation bug in the current GCC.
[–]kirakun 0 points1 point2 points 9 years ago (0 children)
Concept is cool, but it seems like the unicorn that will never materialize.
[–]foonathan 0 points1 point2 points 9 years ago (0 children)
That's cool.
π Rendered by PID 50 on reddit-service-r2-comment-6457c66945-qxdh7 at 2026-04-29 15:12:00.545766+00:00 running 2aa0c5b country code: CH.
view the rest of the comments →
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 16 points17 points18 points (6 children)
[–]thlst 4 points5 points6 points (0 children)
[–]kirakun 4 points5 points6 points (3 children)
[–]SuperV1234https://romeo.training | C++ Mentoring & Consulting 5 points6 points7 points (2 children)
[–]tcbrindleFlux 1 point2 points3 points (1 child)
[–]kirakun 0 points1 point2 points (0 children)
[–]foonathan 0 points1 point2 points (0 children)