I have the following problem:
template< size_t... N_i >
class A
{
public:
// ...
void foo()
{
bar( /* 0,...,0 <- sizeof...(N_i) many */);
}
};
I want to call a function bar and pass sizeof...(N_i) many arguments to it which are all zeros, e.g., bar(0,0,0) in case sizeof...(N_i) == 3.
How can this be implemented?
bar(((void)N_i, 0)...);
The comma operator will discard N_i, yielding just the right-hand operand's value (0). The cast is to prevent a warning about N_i being discarded.
Despite the undoubtedly interesting answer by #Columbo, I want to suggest another viable solution based on constexpr'd template variables:
#include <cstddef>
template<std::size_t, std::size_t V>
constexpr std::size_t repeat_value = V;
template<std::size_t... N_i>
class A {
template<typename... Args>
void bar(Args&&...) { }
public:
void foo() {
// repeat N_i times value 0
bar(repeat_value<N_i, 0>...);
}
};
int main() {
A<0, 1, 2, 3, 4> a;
a.foo();
}
I find it easier to read at least, even if it's bad in terms of performance at compile-time.
You can easily generalize it as it follows:
template<std::size_t, typename T, T V>
constexpr T repeat_value = V;
The invokation in the specific case is this:
bar(repeat_value<N_i, int, 0>...);
You could also use templates to simulate something similar. This is a very basic solution and will just create a list of 0s, but it could be extended to generate other sequences if that was desired.
template <size_t Unused>
struct Wrap {
static constexpr size_t value = 0;
};
template <size_t... N_i>
class A {
public:
void foo() {
bar(Wrap<N_i>::value...);
}
};
Which will just expand into a list of zeros of the same size as the N_i arguments. Admittedly, the interface is slightly different.
For a complete example, which shows the values of the elements which bar receives, see here: Live example
You can also use the fact that if we subtract any positive integer from itself we get 0.
template< size_t... N_i >
class A
{
public:
void foo()
{
//------vvvvvvvvv-------->expand to N_i 0's
bar( (N_i - N_i)...);
}
//for ending recursion
void bar()
{
}
//generalized version
template<typename T, typename... Types>
void bar(T t, Types... types)
{
std::cout << t << "\n";
bar(types...);
}
};
int main()
{
A<1,2,3,4,10> a;
a.foo();
}
Related
Let's say I have the following function declaration:
template<typename signature>
int foo();
Given the above-mentioned function, is it possible to define foo in such a way, so that it returns the number of function arguments that were passed in the decltype template parameter?
So the example usage might look like:
int bar(int a, int b)
{
return a + b;
}
int jar(int a)
{
return a * a;
}
int main()
{
std::cout << foo<decltype(bar)>() << std::endl; // Desired output: 2
std::cout << foo<decltype(jar)>() << std::endl; // Desired output: 1
}
Edit:
Thanks, everyone for the replies. They do seem to work. However, I forgot to mention one more use case.
Let's say I want to get the number of arguments of the following function:
int __stdcall car(int a, int b, int c)
{
return a * b + c;
}
The answers so far do not seem to work with this kind of function that uses __stdcall convention.
Any idea why and what can be done about it?
For that(i.e. with decltype), the given foo is not enough. You need something like the followings traits.
template<typename> struct funtion_args final {};
template<typename ReType, typename... Args>
struct funtion_args<ReType(Args...)> final
{
static constexpr std::size_t noArgs = sizeof...(Args);
};
Used sizeof... operator on the variadic template arguments, to get the no of arguments.
And then you can get the argument count directly like
std::cout << funtion_args<decltype(bar)>::noArgs << "\n"; // output: 2
or pack into the foo
template<typename signature>
constexpr std::size_t foo() noexcept
{
return funtion_args<signature>::noArgs;
}
(See Live Demo)
Better Approach
If you want less typing(i.e. without decltype), a more convenient way of getting the arguments count of a free-function, you could do the following
template <typename ReType, typename... Args>
constexpr auto foo(ReType(*)(Args...)) noexcept
{
return sizeof...(Args);
}
Now you could conveniently call the foo with other functions as arguments
std::cout << foo(bar) << "\n"; // output: 2
(See Live Demo)
Sure, just have foo() call on a suitable trait type. For example:
template <typename T>
struct foo_helper;
template <typename T, typename... Args>
struct foo_helper<T(Args...)> {
static constexpr std::size_t arg_count = sizeof...(Args);
};
template <typename T>
std::size_t foo() {
return foo_helper<T>::arg_count;
}
If I have a class template which contains an array with another class as type with undefined amount of fields (the amount is a template parameter), how do I run their constructors (if they take parameters)?
Here some example code:
class ArrayClass
{
public:
ArrayClass() = delete;
ArrayClass(int anyParameter) {}
};
template <const int amountOfFields>
class ContainingClass
{
ArrayClass myArray[amountOfFields];
public:
ContainingClass();
};
template <const int amountOfFields>
ContainingClass<amountOfFields>::ContainingClass()
:
myArray(5) // doesn't work of cause
{}
Is it possible to give every ArrayClass, no matter how many there are, the same parameter (or different ones)? (I don't essentially need it but it would make things easier for me)
There’s nothing in the C++ standard libraries for this case
If you’re compiling with GCC, it has a proprietary extension called ranged initialization. With GCC, you can write something like this (untested):
template<size_t amountOfFields>
ContainingClass<amountOfFields>::ContainingClass():
myArray( { [0 ... (amountOfFields-1)] = 5} )
{ }
If you’re using any other compiler, you have following options.
As said by the commenters, replace array with std::vector, it has the constructor you need. However this will change RAM layout, i.e. if you have lots of containers with small number of elements each, arrays (both C arrays, and C++ std::array) will be faster because one less pointer to chase.
Remove “=delete” from the default constructor of your ArrayClass, use std::fill or std::fill_n in the ContainingClass constructor to set initial values after they’re already constructed. However this might bring some small runtime cost.
If you don’t have too many elements, technically you can use some template metaprogramming to implement statically-constructed arrays the way you want. However, IMO that’ll be substantial amount of very hard to debug C++ code (there’s no compile-time debugger).
If you have small number of different template arguments in your code, you can write a function like
template<size_t N>
constexpr std::array<ArrayClass,N> fill_array(int val)
specialize it for different values of amountOfFields temple arguments you have, and call the function in the constructor of ContainingClass.
Other solutions are possible, like external tools, macros, boost, etc… But I think 2 & 4 are the most reasonable workarounds.
This work for me with GCC 8.1 / Clang 6.0 and C++14, though I am definitely not sure whether it is Standard compliant:
class E {
public:
E() = delete;
E(int i) : i_(i) { }
operator int() const { return i_; }
private:
int i_;
};
template <typename T>
T dummy(T val, /* [[maybe_unused]] */ size_t I) { return val; }
template <typename T, size_t... I, typename U>
constexpr auto make_array_impl(U val, std::index_sequence<I...> is) {
return std::array<T, is.size()>{dummy(val, I)...};
}
template <typename T, size_t N, typename U>
constexpr auto make_array(U val) {
return make_array_impl<T>(val, std::make_index_sequence<N>{});
}
template <typename T, size_t N>
class A {
public:
A(T val) : a_{make_array<T, N>(val)} { }
void print() { for (auto e : a_) std::cout << e << std::endl; }
private:
std::array<T, N> a_;
};
int main() {
A<E, 5> a(-1);
a.print();
}
Live demo: https://wandbox.org/permlink/Db9Zpf6gUMvg4MER
Updated more generic solution:
template <typename T, size_t... I, typename... Args>
constexpr auto make_array_impl(std::index_sequence<I...> is, Args&&... args) {
return std::array<T, is.size()>{ (I, T(std::forward<Args>(args)...))... };
}
template <typename T, size_t N, typename... Args>
constexpr auto make_array(Args&&... args) {
return make_array_impl<T>(std::make_index_sequence<N>{}, std::forward<Args>(args)...);
}
Suppose we have function such as
template <typename T, unsigned N> void foo();
and for simplicity assume that we know that only (constant) values N_1, N_2 ... N_k are valid for N.
Now, suppose I want to make that compile-time parameter a run-time one, using foo() as a black-box, i.e. implement:
template <typename T> void foo(unsigned n);
by making foo<,>() calls. How should I go about doing that? Obviously, I can write:
template <typename T> void foo(unsigned n) {
switch(n) {
case N_1 : foo<T, N_1>(); break;
case N_2 : foo<T, N_2>(); break;
// etc. etc.
case N_k : foo<T, N_k>(); break;
}
}
... but this makes me feel all dirty. I could use a MAP() meta-macro to generate these k lines, I suppose; but can I do anything better and less-macroish to achieve the same? Is it possible to write something like the above that's general, and works for every variadic template and a fixed sequence of constant values?
Notes:
C++11/14/17-specific suggestions are obviously welcome.
The N's are not necessarily contiguous, nor small, nor sorted. e.g. suppose N_2 = 123456789 and N_5 = 1.
You could make a function pointer table:
using F = void(*)();
template <class T, class >
struct Table;
template <class T, size_t... Is>
struct Table<T, std::index_sequence<Is...> > {
static constexpr F fns[] = {
foo<T, Is>...
};
};
template <class T, size_t... Is>
constexpr F Table<T, std::index_sequence<Is...> >::fns[sizeof...(Is)];
And then just invoke the one you want:
template <class T, size_t N>
struct MakeTable : Table<T, std::make_index_sequence<N>> { };
template <typename T>
void foo(unsigned n) {
MakeTable<T, MaxN>::fns[n]();
}
If the N_ks aren't contiguous, then we can use a lambda for inline parameter unpacking:
template <class T>
void foo(unsigned n) {
using seq = std::index_sequence<N_1, N_2, ..., N_k>;
indexer(seq)([n](auto i){
if (n == i) {
f<T, i>();
}
});
}
If the above is too slow, then I guess just manually build a std::unordered_map<unsigned, void(*)()> or something.
In these kind of situations I like to build a static table of function pointers, with a dynamic parameter deciding which one to dispatch to. Below is an implementation that achieves this, in the function foo_dynamic. To this function, you specify the maximum value of N you'd like to support, and it builds a static table of function pointers using some recursive templates. You then dereference into this table with your dynamic parameter.
using ftype = void (*)();
template <typename T, unsigned N> void foo()
{
std::cout << N << std::endl;
}
template <typename T, unsigned max>
struct TablePopulator
{
static void populateFTable(ftype* table)
{
table[max] = foo<T,max>;
TablePopulator<T,max-1>::populateFTable(table);
}
};
template <typename T>
struct TablePopulator<T, 0>
{
static void populateFTable(ftype* table)
{
table[0] = foo<T,0>;
}
};
template<typename T, unsigned max_N>
std::array<ftype, max_N>& initTable()
{
static std::array<ftype, max_N> table;
TablePopulator<T, max_N-1>::populateFTable(table.data());
return table;
}
template<typename T, unsigned max_N>
void foo_dynamic(unsigned actualN)
{
static auto ftable = initTable<T, max_N>();
if(actualN >= max_N)
throw std::runtime_error("Max param exceeded");
ftable[actualN]();
}
int main()
{
foo_dynamic<int, 10>(1);
foo_dynamic<int, 10>(5);
return 0;
}
EDIT: Given the constraints in the question edit, here's an approach where valid indices are specified manually, which uses an unordered_map instead of an array:
using ftype = void (*)();
template <typename T, unsigned N> void foo()
{
std::cout << N << std::endl;
}
template<typename T, size_t ... Indices>
void foo_dynamic_indices(size_t actual_index)
{
static std::unordered_map<size_t, ftype> fmap = {{Indices, foo<T,Indices>}...};
auto fIt = fmap.find(actual_index);
if(fIt == fmap.end())
throw std::runtime_error("Index not found");
fIt->second();
}
int main()
{
foo_dynamic_indices<int, 0, 3, 400, 1021, 10000000>(10000000);
foo_dynamic_indices<int, 0, 3, 400, 1021, 10000000>(4); //Exception
return 0;
}
Is it possible to iterate over all elements in a struct or class?
For example if I have a struct of three elements of different type:
struct A {
classA a;
classB b;
classC c;
};
then I need some iterator such that a method next() would give me the value
of the next element. The problem is that as you see, the values have different types.
Nope, not with the language as it is.
You could do it by deriving your classes from a common base, and then implementing your own iterator to return pointers to each item as the iterator is traversed.
Alternatively put the items in a std::vector and use that to provide the iteration.
No, there is no reflection in C++, (yet, there are murmurs about static reflection coming one day).
Anyway, there is a way to work around this, to an extent - first of all, you'll need a (temporary) tuple with references to your data members.
Then you will need a construct "iterating" over the tuple, such as:
void applyToAll() { }
template <typename Lambda, typename... Lambdas>
void applyToAll(Lambda&& closure, Lambdas&&... closures) {
std::forward<Lambda>(closure)();
applyToAll(std::forward<Lambdas>(closures)...);
}
// use your favourite sequence-making trick
template <unsigned... Is>
struct _Sequence {
typedef _Sequence<Is...> type;
};
template <unsigned Max, unsigned... Is>
struct _MakeSequence : _MakeSequence<Max - 1, Max - 1, Is...> { };
template <unsigned... Is>
struct _MakeSequence<0, Is...> : _Sequence<Is...> { };
template <typename Tuple, typename Functor, unsigned... Is>
void _foreachElemInTuple(_Sequence<Is...>, Tuple&& t, Functor&& f) {
applyToAll(
[&]{ std::forward<Functor>(f)(std::get<Is>(std::forward<Tuple>(t))); }...
);
}
template <typename Tuple, typename Functor>
void foreachElemInTuple(Tuple&& t, Functor&& f) {
_foreachElemInTuple(
_MakeSequence<std::tuple_size<
typename std::decay<Tuple>::type>::value>(),
std::forward<Tuple>(t), std::forward<Functor>(f)
);
}
Then you can call foreachElemInTuple(yourTuple, some_adapter()).
Your adapter will look like:
struct some_adapter {
template <typename... Args>
// A little bit of C++14, you can also just -> decltype the thing
decltype(auto) operator()(Args&& ... args) const {
return doStuff(std::forward<Args>(args)...);
}
};
As everyone else says, you cannot directly iterate over data members of a
class. However, it is not difficult to do it indirectly, provided of course that
you can access each of the data members you want to iterate over. The idea
in essense, as per ScarletAmaranth's solution, is to iterate over an std::tuple
of references to those data members.
The following program shows how to obtain such a tuple, using std::forward_as_tuple,
and another way to do the iterating by compiletime recursion, without
auxiliary apparatus.
#include <tuple>
/* You want to be able do something with the values of the members of an `A`
in turn.
*/
struct A
{
char ch;
int i;
double d;
// May also have members of class type. It doesn't matter
};
/* 1) Provide yourself with the means of creating a sequence that contains
references to the data members of a given `A`
*/
std::tuple<char const &, int const &, double const &> get_A_vals(A const & a)
{
return std::forward_as_tuple(a.ch,a.i,a.d);
}
/* 2) Provide yourself with a means of applying some operation, `Func`,
to each element of an `std::tuple`
*/
template<size_t I = 0, typename Func, typename ...Ts>
typename std::enable_if<I == sizeof...(Ts)>::type
for_each_in_tuple(std::tuple<Ts...> const &, Func) {}
template<size_t I = 0, typename Func, typename ...Ts>
typename std::enable_if<I < sizeof...(Ts)>::type
for_each_in_tuple(std::tuple<Ts...> const & tpl, Func func)
{
func(std::get<I>(tpl));
for_each_in_tuple<I + 1>(tpl,func);
}
/* 3) Combine 1) and 2) to apply `Func` over the members of an `A`
*/
template<typename Func>
void for_each_in_A(A const & a, Func func)
{
for_each_in_tuple(get_A_vals(a),func);
}
// Testing...
#include <iostream>
// A specimen operation: just prints its argument
struct printer
{
template<typename T>
void operator () (T && t)
{
std::cout << t << std::endl;
}
};
int main()
{
A a{'a',1,2.0};
for_each_in_A(a,printer());
return 0;
}
// EOF
The program outputs:
a
1
2
If you have control of the structs or classes over whose members you need to
iterate, you may consider whether it is practical simply to dispense with them
and use the corresponding std::tuples everywhere.
Code built with gcc 4.8.2 and clang 3.3, -std=c++11.
The following simple code pattern is very common in graphics programming.
It creates an array of layers and loops over them.
struct Layer
{
int n;
void operator()(float value)
{
}
};
struct AnotherLayer
{
int n;
int m;
void operator()(float value)
{
}
};
void process_layers(Layer_t* layer, size_t size, float value)
{
for (size_t n = 0; n < size; ++n)
layer[n](value);
}
Layer a = {1};
Layer b = {2};
AnotherLayer c = {2,3};
typedef std::function < void (float) > Layer_t;
Layer_t layers [] = {a,b,c};
process_layers(layers, sizeof(layers)/sizeof(Layer), 100);
I would like to convert this to use varadic templates in c++11. Any ideas how I could do this. This is what I would like it to look like. Any ideas? Is this even possible?
template <int n>
struct Layer
{
void operator()(float value)
{
}
};
template <int n, int m>
struct AnotherLayer
{
void operator()(float value)
{
}
};
template <typename Layer1, typename Layer2, ...>
struct Layers //process_layers
{
void operator()(float value)
{
for (size_t n = 0; n < SIZEOF(Layer1,Layer2,...); ++n)
Layer[N]()(value);
}
};
Then I could do this.
typedef Layers<Layer<1>, Layer<2>, AnotherLayer<3,8> > funky_layer_t;
typedef Layers<Layer<4>, Layer<5>, Layer<5>, AnotherLayer<6,7> > standard_layer_t;
typedef Layers<funky_layer_t, standard_layer_t> awesome_layer_t;
awesome_layer_t()(100);
Note: with the second approach, all paramaters to construct layers are known at compile time.
The example you give is very simple to re-do with variadic templates.
template<typename Func> void process(Func &&f) {} // base case for zero items
// overload for at least one item
template<typename Func, typename FirstItem, typename... Items>
void process(Func &&f, FirstItem &&fi, Items &&...is) {
std::forward<Func>(f)(std::forward<FirstItem>(fi)); // f(fi);
process(std::forward<Func>(f), std::forward<Items>(is)...); // process(f,is...);
}
Layer a = {1};
Layer b = {2};
Layer c = {3};
process([](Layer &l){ l(100); },
a, b, c);
Also notice that this avoids all the unnecessary copies in the original. (Though of course you could also avoid them just by doing Layer layers[] = {{1},{2},{3}};)
I'm not exactly sure how your later comments and code are related to running an operation over a collection of layers.
What exactly is the computation you want to perform at compile-time?
To adjust for the new example the process() does not need to change at all, you only need to create a functor that can handle each type. (polymorphic lambdas would help here, but we'll have to make due with an explicit functor type)
Layer a = {1};
Layer b = {2};
AnotherLayer c = {2,3};
struct TheOperation {
template<typename T>
void operator() (T &t) {
t(100);
}
};
process(TheOperation(),
a, b, c);
Here's your awesome_layer_t transcribed to correct variadic template syntax, but I still don't see what you want to accomplish, so I can't say if this is a good way to do it or not. This doesn't actually call the operator()s at compile-time, it only arranges to have a bunch of objects default constructed at runtime and then operator() called, again, at runtime.
template <int n>
struct Layer
{
int operator()(float value)
{
std::printf("L %d %e\n",n,value);
return 0;
}
};
template <int n, int m>
struct AnotherLayer
{
int operator()(float value)
{
std::printf("AL %d %d %e\n",n,m,value);
return 0;
}
};
template <typename... Ls>
struct Layers //process_layers
{
int operator()(float value)
{
struct Tmp {
void operator() (...) {}
};
Tmp()( Ls()(value)...);
return 0;
}
};
typedef Layers<Layer<1>, Layer<2>, AnotherLayer<3,8> > funky_layer_t;
typedef Layers<Layer<4>, Layer<5>, Layer<5>, AnotherLayer<6,7> > standard_layer_t;
typedef Layers<funky_layer_t, standard_layer_t> awesome_layer_t;
int main() {
awesome_layer_t()(100);
}
I believe that you can do this using normal function templates as follows:
/* Base case: If you have no layers to apply, do nothing. */
void executeLayers() {
// Deliberately empty.
}
/* Recursive step: If you have at least one layer, apply it, then apply the
* remaining layers.
*/
template <typename Head, typename... Tail>
void executeLayers(Head head, Tail... tail) {
head(); // Execute the first layer
executeLayers(tail); // Execute the remaining layers
}
You could then do something like this:
executeLayers(layer1, layer2, layer3, layer4, layer5);
Hope this helps!