I am writing a simple test program using TMP to calculate the Nth fibonacci number. I have already found many ways to do this, but I'm just trying out a bunch of ways to get my understanding better. The way I am having a problem with is this:
template<int A>
struct fib
{
static const bool value = (A<2);
static const int num = (value?A:(fib<A-1>::num + fib<A-2>::num));
};
The error message I am getting is:
error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) instantiating 'fib<-1796>::value'|
I have tried substituting many values into the "false" field of the ternary, just to play with it and see what it does. I still do not understand why this does not work. Can anyone help me and tell me why? Thanks.
EDIT: My guess is that the compiler might be evaluating the T/F fields of the ternary before checking to see if the value is true or false, but I'm not sure since that's not how an if statement is supposed to work at all, and these are supposed to roughly emulate if statements
I must admit that I'm not that experienced concerning template programming. But in OP's case, a simple solution would be template specialization.
Sample code:
#include <iostream>
template<int A>
struct fib
{
static const int num = fib<A-1>::num + fib<A-2>::num;
};
template<>
struct fib<1>
{
static const int num = 1;
};
template<>
struct fib<2>
{
static const int num = 1;
};
int main()
{
fib<10> fib10;
std::cout << "fib<10>: " << fib10.num << '\n';
return 0;
}
Output:
fib<10>: 55
Live Demo on coliru
One way to write this in a more straightforward manner is to use if constexpr. Unlike with regular if (and with the ternary operator), templates in the not taken branch are not instantiated.
template <int n>
struct fib {
constexpr static int eval() {
if constexpr (n < 2)
return n;
else
return fib<n-1>::eval() + fib<n-2>::eval();
}
};
Of course once you have if constexpr you don't really need templates to make a compile-time function of this type. A constexpr non-template function will do just fine. This is just an illustration of the technique.
The first comment on my original post is the correct answer. The author is (n.m.). Template type instantiations are evaluated in both fields of the ternary, while the object instantiation itself is not. To solve this, I will look into std::condiditional or std::enable_if
I want to optimize a little programm/library i'm writing and since 2 weeks i'm somewhat stuck and now wondering if what i had in mind is even possible like that.
(Please be gentle i don't have very much experience in meta-programming.)
My goal is of course to have certain computations be done by the compiler, so that the programmer - hopefully - only has to edit code at one point in the program and have the compiler "create" all the boilerplate. I do have a resonably good idea how to do what i want with macros, but it is wished that i do it with templates if possible.
My goal is:
Lets say i have a class that a using programmer can derive from. There he can have multiple incoming and outgoing datatypes that i want to register somehow so that the base class can do i'ts operations on them.
class my_own_multiply : function_base {
in<int> a;
in<float> b;
out<double> c;
// ["..."] // other content of the class that actually does something but is irrelevant
register_ins<a, b> ins_of_function; // example meta-function calls
register_outs<c> outs_of_function;
}
The meta-code i have up till now is this: (but it's not jet working/complete)
template <typename... Ts>
struct register_ins {
const std::array<std::unique_ptr<in_type_erasured>, sizeof...(Ts)> ins;
constexpr std::array<std::unique_ptr<in_type_erasured>, sizeof...(Ts)>
build_ins_array() {
std::array<std::unique_ptr<in_type_erasured>, sizeof...(Ts)> ins_build;
for (unsigned int i = 0; i < sizeof...(Ts); ++i) {
ins_build[i] = std::make_unique<in_type_erasured>();
}
return ins_build;
}
constexpr register_ins() : ins(build_ins_array()) {
}
template <typename T>
T getValueOf(unsigned int in_nr) {
return ins[in_nr]->getValue();
}
};
As you may see, i want to call my meta-template-code with a variable number of ins. (Variable in the sens that the programmer can put however many he likes in there, but they won't change at runtime so they can be "baked" in at compile time)
The meta-code is supposed to be creating an array, that is of the lengt of the number of ins and is initialized so that every field points to the original in in the my_own_multiply class. Basically giving him an indexable data structure that will always have the correct size. And that i could access from the function_base class to use all ins for certain functions wich are also iterable making things convinient for me.
Now i have looked into how one might do that, but i now am getting the feeling that i might not really be allowed to "create" this array at compile time in a fashion that allows me to still have the ins a and b be non static and non const so that i can mutate them. From my side they wouldn't have to be const anyway, but my compliler seems to not like them to be free. The only thing i need const is the array with the pointers. But using constexpr possibly "makes" me make them const?
Okay, i will clarify what i don't get:
When i'm trying to create an "instance" of my meta-stuff-structure then it fails because it expects all kinds of const, constexpr and so on. But i don't want them since i need to be able to mutate most of those variables. I only need this meta-stuff to create an array of the correct size already at compile time. But i don't want to sacrifice having to make everything static and const in order to achive this. So is this even possible under these kinds of terms?
I do not get all the things you have in mind (also regarding that std::unique_ptr in your example), but maybe this helps:
Starting from C++14 (or C++11, but that is strictly limited) you may write constexpr functions which can be evaluated at compile-time. As a precondition (in simple words), all arguments "passed by the caller" must be constexpr. If you want to enforce that the compiler replaces that "call" by the result of a compile-time computation, you must assign the result to a constexpr.
Writing usual functions (just with constexpr added) allows to write code which is simple to read. Moreover, you can use the same code for both: compile-time computations and run-time computations.
C++17 example (similar things are possible in C++14, although some stuff from std is just missing the constexpr qualifier):
http://coliru.stacked-crooked.com/a/154e2dfcc41fb6c7
#include <cassert>
#include <array>
template<class T, std::size_t N>
constexpr std::array<T, N> multiply(
const std::array<T, N>& a,
const std::array<T, N>& b
) {
// may be evaluated in `constexpr` or in non-`constexpr` context
// ... in simple man's words this means:
// inside this function, `a` and `b` are not `constexpr`
// but the return can be used as `constexpr` if all arguments are `constexpr` for the "caller"
std::array<T, N> ret{};
for(size_t n=0; n<N; ++n) ret[n] = a[n] * b[n];
return ret;
}
int main() {
{// compile-time evaluation is possible if the input data is `constexpr`
constexpr auto a = std::array{2, 4, 6};
constexpr auto b = std::array{1, 2, 3};
constexpr auto c = multiply(a, b);// assigning to a `constexpr` guarantees compile-time evaluation
static_assert(c[0] == 2);
static_assert(c[1] == 8);
static_assert(c[2] == 18);
}
{// for run-time data, the same function can be used
auto a = std::array{2, 4, 6};
auto b = std::array{1, 2, 3};
auto c = multiply(a, b);
assert(c[0] == 2);
assert(c[1] == 8);
assert(c[2] == 18);
}
return 0;
}
I am looking for an idiomatic way to optimize this template I wrote.
My main concern is how to correctly define the template parameter n and using it as a return parameter while the user must not overwrite it.
I am also open for other suggestions on how to write this template in an idiomatic C++14 way.
template<
typename InType=uint32_t,
typename OutType=float,
unsigned long bits=8,
unsigned long n=(sizeof(InType) * 8) / bits
>
std::array<OutType,n> hash_to_color(InType in) noexcept {
InType mask = ~0;
mask = mask << bits;
mask = ~mask;
std::array<OutType,n> out;
auto out_max = static_cast<OutType>((1 << bits) - 1);
for (auto i = 0; i < n; i++) {
auto selected = (in >> (i * bits)) & mask;
out[i] = static_cast<OutType>(selected) / out_max;
}
return out;
}
Regarding the n template parameter, you can avoid it by using auto as the return type in C++14. Here's a simpler example of the principle:
template<int N>
auto f()
{
constexpr int bar = N * 3;
std::array<int, bar> foo;
return foo;
}
Naturally the calculation of the array template parameter must be a constant expression.
Another option (compatible with C++11) is trailing-return-type:
template<int N>
auto f() -> std::array<int, N * 3>
{
This is a wee bit more verbose than taking advantage of C++14's allowing of return type deduction from the return statement.
Note: ~0 in your code is wrong because 0 is an int, it should be ~(InType)0. Also (1 << bits) - 1 has potential overflow issues.
I think M.M.'s answer is excellent, and, in your case, I'd definitely use one of the two alternatives suggested there.
Suppose you later encounter a situation where the logic is, given n, use not 3 n, but something more complicated, e.g., n2 + 3 n + 1. Alternatively, maybe the logic is not very complicated, but it is subject to change.
The first option - using automatically deduced auto, is pithy, but the omission sometimes makes the declaration less clear.
The second option - trailing return type - violates DRY to some extent.
(Just to clarify again, I don't think that these are significant problems in the context of your question or M.M.'s answer.)
So, a third option would be to factor out the logic to a constexpr function:
#include <array>
constexpr int arr_size(int n) { return n * n + 3 * n + 1; }
Since it's constexpr, it can be used to instantiate the template:
template<int N>
std::array<int, arr_size(N)> f() {
return std::array<int, arr_size(N)>();
}
Note that now the function has an explicit return type, but the logic of arr_size appears only once.
You could use this as usual:
int main() {
auto a = f<10>();
a[0] = 3;
}
Not entirely a question, although just something I have been pondering on how to write such code more elegantly by style and at the same time fully making use of the new c++ standard etc. Here is the example
Returning Fibonacci sequence to a container upto N values (for those not mathematically inclined, this is just adding the previous two values with the first two values equal to 1. i.e. 1,1,2,3,5,8,13, ...)
example run from main:
std::vector<double> vec;
running_fibonacci_seq(vec,30000000);
1)
template <typename T, typename INT_TYPE>
void running_fibonacci_seq(T& coll, const INT_TYPE& N)
{
coll.resize(N);
coll[0] = 1;
if (N>1) {
coll[1] = 1;
for (auto pos = coll.begin()+2;
pos != coll.end();
++pos)
{
*pos = *(pos-1) + *(pos-2);
}
}
}
2) the same but using rvalue && instead of & 1.e.
void running_fibonacci_seq(T&& coll, const INT_TYPE& N)
EDIT: as noticed by the users who commented below, the rvalue and lvalue play no role in timing - the speeds were actually the same for reasons discussed in the comments
results for N = 30,000,000
Time taken for &:919.053ms
Time taken for &&: 800.046ms
Firstly I know this really isn't a question as such, but which of these or which is best modern c++ code? with the rvalue reference (&&) it appears that move semantics are in place and no unnecessary copies are being made which makes a small improvement on time (important for me due to future real-time application development). some specific ''questions'' are
a) passing a container (which was vector in my example) to a function as a parameter is NOT an elegant solution on how rvalue should really be used. is this fact true? if so how would rvalue really show it's light in the above example?
b) coll.resize(N); call and the N=1 case, is there a way to avoid these calls so the user is given a simple interface to only use the function without creating size of vector dynamically. Can template metaprogramming be of use here so the vector is allocated with a particular size at compile time? (i.e. running_fibonacci_seq<30000000>) since the numbers can be large is there any need to use template metaprogramming if so can we use this (link) also
c) Is there an even more elegant method? I have a feeling std::transform function could be used by using lambdas e.g.
void running_fibonacci_seq(T&& coll, const INT_TYPE& N)
{
coll.resize(N);
coll[0] = 1;
coll[1] = 1;
std::transform (coll.begin()+2,
coll.end(), // source
coll.begin(), // destination
[????](????) { // lambda as function object
return ????????;
});
}
[1] http://cpptruths.blogspot.co.uk/2011/07/want-speed-use-constexpr-meta.html
Due to "reference collapsing" this code does NOT use an rvalue reference, or move anything:
template <typename T, typename INT_TYPE>
void running_fibonacci_seq(T&& coll, const INT_TYPE& N);
running_fibonacci_seq(vec,30000000);
All of your questions (and the existing comments) become quite meaningless when you recognize this.
Obvious answer:
std::vector<double> running_fibonacci_seq(uint32_t N);
Why ?
Because of const-ness:
std::vector<double> const result = running_fibonacci_seq(....);
Because of easier invariants:
void running_fibonacci_seq(std::vector<double>& t, uint32_t N) {
// Oh, forgot to clear "t"!
t.push_back(1);
...
}
But what of speed ?
There is an optimization called Return Value Optimization that allows the compiler to omit the copy (and build the result directly in the caller's variable) in a number of cases. It is specifically allowed by the C++ Standard even when the copy/move constructors have side effects.
So, why passing "out" parameters ?
you can only have one return value (sigh)
you may wish the reuse the allocated resources (here the memory buffer of t)
Profile this:
#include <vector>
#include <cstddef>
#include <type_traits>
template <typename Container>
Container generate_fibbonacci_sequence(std::size_t N)
{
Container coll;
coll.resize(N);
coll[0] = 1;
if (N>1) {
coll[1] = 1;
for (auto pos = coll.begin()+2;
pos != coll.end();
++pos)
{
*pos = *(pos-1) + *(pos-2);
}
}
return coll;
}
struct fibbo_maker {
std::size_t N;
fibbo_maker(std::size_t n):N(n) {}
template<typename Container>
operator Container() const {
typedef typename std::remove_reference<Container>::type NRContainer;
typedef typename std::decay<NRContainer>::type VContainer;
return generate_fibbonacci_sequence<VContainer>(N);
}
};
fibbo_maker make_fibbonacci_sequence( std::size_t N ) {
return fibbo_maker(N);
}
int main() {
std::vector<double> tmp = make_fibbonacci_sequence(30000000);
}
the fibbo_maker stuff is just me being clever. But it lets me deduce the type of fibbo sequence you want without you having to repeat it.
C++ Notes: Array Initialization has a nice list over initialization of arrays. I have a
int array[100] = {-1};
expecting it to be full with -1's but its not, only first value is and the rest are 0's mixed with random values.
The code
int array[100] = {0};
works just fine and sets each element to 0.
What am I missing here.. Can't one initialize it if the value isn't zero ?
And 2: Is the default initialization (as above) faster than the usual loop through the whole array and assign a value or does it do the same thing?
Using the syntax that you used,
int array[100] = {-1};
says "set the first element to -1 and the rest to 0" since all omitted elements are set to 0.
In C++, to set them all to -1, you can use something like std::fill_n (from <algorithm>):
std::fill_n(array, 100, -1);
In portable C, you have to roll your own loop. There are compiler-extensions or you can depend on implementation-defined behavior as a shortcut if that's acceptable.
There is an extension to the gcc compiler which allows the syntax:
int array[100] = { [0 ... 99] = -1 };
This would set all of the elements to -1.
This is known as "Designated Initializers" see here for further information.
Note this isn't implemented for the gcc c++ compiler.
The page you linked to already gave the answer to the first part:
If an explicit array size is
specified, but an shorter
initiliazation list is specified, the
unspecified elements are set to zero.
There is no built-in way to initialize the entire array to some non-zero value.
As for which is faster, the usual rule applies: "The method that gives the compiler the most freedom is probably faster".
int array[100] = {0};
simply tells the compiler "set these 100 ints to zero", which the compiler can optimize freely.
for (int i = 0; i < 100; ++i){
array[i] = 0;
}
is a lot more specific. It tells the compiler to create an iteration variable i, it tells it the order in which the elements should be initialized, and so on. Of course, the compiler is likely to optimize that away, but the point is that here you are overspecifying the problem, forcing the compiler to work harder to get to the same result.
Finally, if you want to set the array to a non-zero value, you should (in C++, at least) use std::fill:
std::fill(array, array+100, 42); // sets every value in the array to 42
Again, you could do the same with an array, but this is more concise, and gives the compiler more freedom. You're just saying that you want the entire array filled with the value 42. You don't say anything about in which order it should be done, or anything else.
C++11 has another (imperfect) option:
std::array<int, 100> a;
a.fill(-1);
With {} you assign the elements as they are declared; the rest is initialized with 0.
If there is no = {} to initalize, the content is undefined.
Using std::array, we can do this in a fairly straightforward way in C++14. It is possible to do in C++11 only, but slightly more complicated.
Our interface is a compile-time size and a default value.
template<typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, 0>, T &&) {
return std::array<std::decay_t<T>, 0>{};
}
template<std::size_t size, typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, size>, T && value) {
return detail::make_array_n_impl<size>(std::forward<T>(value), std::make_index_sequence<size - 1>{});
}
template<std::size_t size, typename T>
constexpr auto make_array_n(T && value) {
return make_array_n(std::integral_constant<std::size_t, size>{}, std::forward<T>(value));
}
The third function is mainly for convenience, so the user does not have to construct a std::integral_constant<std::size_t, size> themselves, as that is a pretty wordy construction. The real work is done by one of the first two functions.
The first overload is pretty straightforward: It constructs a std::array of size 0. There is no copying necessary, we just construct it.
The second overload is a little trickier. It forwards along the value it got as the source, and it also constructs an instance of make_index_sequence and just calls some other implementation function. What does that function look like?
namespace detail {
template<std::size_t size, typename T, std::size_t... indexes>
constexpr auto make_array_n_impl(T && value, std::index_sequence<indexes...>) {
// Use the comma operator to expand the variadic pack
// Move the last element in if possible. Order of evaluation is well-defined
// for aggregate initialization, so there is no risk of copy-after-move
return std::array<std::decay_t<T>, size>{ (static_cast<void>(indexes), value)..., std::forward<T>(value) };
}
} // namespace detail
This constructs the first size - 1 arguments by copying the value we passed in. Here, we use our variadic parameter pack indexes just as something to expand. There are size - 1 entries in that pack (as we specified in the construction of make_index_sequence), and they have values of 0, 1, 2, 3, ..., size - 2. However, we do not care about the values (so we cast it to void, to silence any compiler warnings). Parameter pack expansion expands out our code to something like this (assuming size == 4):
return std::array<std::decay_t<T>, 4>{ (static_cast<void>(0), value), (static_cast<void>(1), value), (static_cast<void>(2), value), std::forward<T>(value) };
We use those parentheses to ensure that the variadic pack expansion ... expands what we want, and also to ensure we are using the comma operator. Without the parentheses, it would look like we are passing a bunch of arguments to our array initialization, but really, we are evaluating the index, casting it to void, ignoring that void result, and then returning value, which is copied into the array.
The final argument, the one we call std::forward on, is a minor optimization. If someone passes in a temporary std::string and says "make an array of 5 of these", we would like to have 4 copies and 1 move, instead of 5 copies. The std::forward ensures that we do this.
The full code, including headers and some unit tests:
#include <array>
#include <type_traits>
#include <utility>
namespace detail {
template<std::size_t size, typename T, std::size_t... indexes>
constexpr auto make_array_n_impl(T && value, std::index_sequence<indexes...>) {
// Use the comma operator to expand the variadic pack
// Move the last element in if possible. Order of evaluation is well-defined
// for aggregate initialization, so there is no risk of copy-after-move
return std::array<std::decay_t<T>, size>{ (static_cast<void>(indexes), value)..., std::forward<T>(value) };
}
} // namespace detail
template<typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, 0>, T &&) {
return std::array<std::decay_t<T>, 0>{};
}
template<std::size_t size, typename T>
constexpr auto make_array_n(std::integral_constant<std::size_t, size>, T && value) {
return detail::make_array_n_impl<size>(std::forward<T>(value), std::make_index_sequence<size - 1>{});
}
template<std::size_t size, typename T>
constexpr auto make_array_n(T && value) {
return make_array_n(std::integral_constant<std::size_t, size>{}, std::forward<T>(value));
}
struct non_copyable {
constexpr non_copyable() = default;
constexpr non_copyable(non_copyable const &) = delete;
constexpr non_copyable(non_copyable &&) = default;
};
int main() {
constexpr auto array_n = make_array_n<6>(5);
static_assert(std::is_same<std::decay_t<decltype(array_n)>::value_type, int>::value, "Incorrect type from make_array_n.");
static_assert(array_n.size() == 6, "Incorrect size from make_array_n.");
static_assert(array_n[3] == 5, "Incorrect values from make_array_n.");
constexpr auto array_non_copyable = make_array_n<1>(non_copyable{});
static_assert(array_non_copyable.size() == 1, "Incorrect array size of 1 for move-only types.");
constexpr auto array_empty = make_array_n<0>(2);
static_assert(array_empty.empty(), "Incorrect array size for empty array.");
constexpr auto array_non_copyable_empty = make_array_n<0>(non_copyable{});
static_assert(array_non_copyable_empty.empty(), "Incorrect array size for empty array of move-only.");
}
The page you linked states
If an explicit array size is specified, but an shorter initiliazation list is specified, the unspecified elements are set to zero.
Speed issue: Any differences would be negligible for arrays this small. If you work with large arrays and speed is much more important than size, you can have a const array of the default values (initialized at compile time) and then memcpy them to the modifiable array.
Another way of initializing the array to a common value, would be to actually generate the list of elements in a series of defines:
#define DUP1( X ) ( X )
#define DUP2( X ) DUP1( X ), ( X )
#define DUP3( X ) DUP2( X ), ( X )
#define DUP4( X ) DUP3( X ), ( X )
#define DUP5( X ) DUP4( X ), ( X )
.
.
#define DUP100( X ) DUP99( X ), ( X )
#define DUPx( X, N ) DUP##N( X )
#define DUP( X, N ) DUPx( X, N )
Initializing an array to a common value can easily be done:
#define LIST_MAX 6
static unsigned char List[ LIST_MAX ]= { DUP( 123, LIST_MAX ) };
Note: DUPx introduced to enable macro substitution in parameters to DUP
For the case of an array of single-byte elements, you can use memset to set all elements to the same value.
There's an example here.
The simplest way is to use std::array and write a function template that will return the required std::array with all of its element initialized with the passed argument as shown below.
C++11 Version
template<std::size_t N> std::array<int, N> make_array(int val)
{
std::array<int, N> tempArray{};
for(int &elem:tempArray)
{
elem = val;
}
return tempArray;
}
int main()
{
//---------------------V-------->number of elements
auto arr = make_array<8>(5);
//------------------------^---->value of element to be initialized with
//lets confirm if all objects have the expected value
for(const auto &elem: arr)
{
std::cout << elem << std::endl; //prints all 5
}
}
Working demo
C++17 Version
With C++17 you can add constexpr to the function template so that it can be used in constexpr context:
//-----------------------------------------vvvvvvvvv--->added constexpr
template<std::size_t N> std::array<int, N> constexpr make_array(int val)
{
std::array<int, N> tempArray{};
for(int &elem:tempArray)
{
elem = val;
}
return tempArray;
}
int main()
{
//--vvvvvvvvv------------------------------>constexpr added
constexpr auto arr = make_array<8>(5);
for(const auto &elem: arr)
{
std::cout << elem << std::endl;
}
}
Working demo
1) When you use an initializer, for a struct or an array like that, the unspecified values are essentially default constructed. In the case of a primitive type like ints, that means they will be zeroed. Note that this applies recursively: you could have an array of structs containing arrays and if you specify just the first field of the first struct, then all the rest will be initialized with zeros and default constructors.
2) The compiler will probably generate initializer code that is at least as good as you could do by hand. I tend to prefer to let the compiler do the initialization for me, when possible.
In the C++ programming language V4, Stroustrup recommends using vectors or valarrays over builtin arrays. With valarrary's, when you create them, you can init them to a specific value like:
valarray <int>seven7s=(7777777,7);
To initialize an array 7 members long with "7777777".
This is a C++ way of implementing the answer using a C++ data structure instead of a "plain old C" array.
I switched to using the valarray as an attempt in my code to try to use C++'isms v. C'isms....