How to pass a variable to a template metafunction? - c++

im currently trying to learn how to use template metaprogramming to write functional code in c++
Heres my attempt at a recursive fibonacci sequence generator
template<int i, int x = 0, int y = 1>
struct Fib : Fib<i-1, y, x+y> {};
template<int x, int y>
struct Fib<0, x, y> {
enum { value = x };
};
This seems to work fine for getting values.
However, When trying to pass a variable as an argument to the template like Fib<i>::value i get the compiler error:
the value of ā€˜iā€™ is not usable in a constant expression.
My main question here is how to avoid or get around this error?
but i also have questions about how to use this kind of code to write things to stdout, not sure where i could implement a cout in all of this

There is no way to "avoid or get around this error".
This is fundamental to C++: template parameters must be compile time constant expressions. That means that the values (or types) of template parameters must be fully defined at compile time.
An ordinary variable is something whose value is determined at run time. Therefore ordinary variables cannot be used as template parameters.
The only exception to this are special kind of variables called constexpr variables, which are variables that have defined constant values that are fully determined at compile time, too. As such, constexpr variables can be used as template parameters because they meet the requirements of a compile time constant expression.
But if you want to generate a Fibonacci sequence specified by a non-constexpr variable you just have to write an ordinary function that does that.

how to use template metaprogramming to write functional code in c++
You might be approaching the subject from a wrong angle. Metaprogramming involves writing instructions for how to write programs, reaching a level of abstraction beyond normal programming. (For more information, I recommend A: What is metaprogramming? by ShuggyCoUk.)
When you write a class template, you are not defining a class. Rather, you write instructions that tell the compiler how to write variations of a class definition that are adapted to different scenarios. Read that sentence again, but with the recognition that "instructions for a computer" means "a program" and that "a class definition" is part of a program. That sentence basically says that writing a (class) template is writing a program that writes (part of) a program. Programs that write programs is the "meta" aspect of "metaprogramming".
Now think about the life cycle of a typical C++ program. Source code is written, the program is converted by a compiler to an executable, then the executable is run. Write, compile, then run, as three disjoint steps. Let's assume that adding steps to this sequence is not an option. (Other languages may choose a different approach.) If the program produced by metaprogramming is to become executable, that program better exist before the compiler is done.
That is the key aspect of metaprogramming as it relates to this question. Metaprograms are written at the same time as other code, and the resulting program is run at the same times as normal. The conversion from "metaprogram" to "program" occurs during compilation. The metaprogram is "executed" by the compiler to produce program pieces that are then incorporated into the rest of your code. Metaprogramming targets the compiler. All inputs to metaprograms must be known by the compiler, hence known at the time of compilation.
The values of most variables are not known to the compiler, as the values often change while the program runs. These values cannot be used as inputs to C++ metaprogramming. The exceptions are variables marked as constexpr, a marking that means the value is knowable by the compiler. A constexpr variable can be used as a template argument; other variables cannot.
Specific case: Fibonacci
Your Fib example tells the compiler how to define each member of a family of structs. For any triple of ints, the compiler can apply your template to generate the definition of the corresponding struct. There happens to be a way to get certain Fibonacci numbers from certain members of this family, but at its core, you have simply written the instructions for defining the members of this family.
The compiler is not going to create every possible member of this family. (Even with the smallest allowable int implementation, there are over 200 trillion members of this family.) Rather, the compiler will create just those members that it knows it needs. You can get the compiler to produce any specific Fibonacci number (up to certain implementation limits), but it will not produce every Fibonacci number (even subject to the limitation that the number be small enough to fit in an int).
Metaprogramming is useful for calculating based on values known at compile-time, but to calculate based on run-time values, you need a run-time function. Use the right tool for the job.

Related

How does c++11 resolve constexpr into assembly?

The basic question:
Edit: v-The question-v
class foo {
public:
constexpr foo() { }
constexpr int operator()(const int& i) { return int(i); }
}
Performance is a non-trivial issue. How does the compiler actually compile the above? I know how I want it to be resolved, but how does the specification actually specify it will be resolved?
1) Seeing the type int has a constexpr constructor, create a int object and compile the string of bytes that make the type from memory into the code directly?
2) Replace any calls to the overload with a call to the 'int's constructor that for some unknown reason int doesn't have constexpr constructors? (Inlining the call.)
3) Create a function, call the function, and have that function call 'int's consctructor?
Why I want to know, and how I plan to use the knowledge
edit:v-Background only-v
The real library I'm working with uses template arguments to decide how a given type should be passed between functions. That is, by reference or by value because the exact size of the type is unknown. It will be a user's responsibility to work within the limits I give them, but I want these limits to be as light and user friendly as I can sanely make them.
I expect a simple single byte character to be passed around in which case it should be passed by value. I do not bar 300mega-byte behemoth that does several minuets of recalculation every time a copy constructor is invoked. In which case passing by reference makes more sense. I have only a list of requirements that a type must comply with, not set cap on what a type can or can not do.
Why I want to know the answer to my question is so I can in good faith make a function object that accepts this unknown template, and then makes a decision how, when, or even how much of a object should be copied. Via a virtual member function and a pointer allocated with new is so required. If the compiler resolves constexpr badly I need to know so I can abandon this line of thought and/or find a new one. Again, It will be a user's responsibility to work within the limits I give them, but I want these limits to be as light and user friendly as I can sanely make them.
Edit: Thank you for your answers. The only real question was the second sentence. It has now been answered. Everything else If more background is required, Allow me to restate the above:
I have a template with four argument. The goal of the template is a routing protocol. Be that TCP/IP -unlikely- or node to node within a game -possible. The first two are for data storage. They have no requirement beyond a list of operators for each. The last two define how the data is passed within the template. By default this is by reference. For performance and freedom of use, these can be changed define to pass information by value at a user's request.
Each is expect to be a single byte long. They could in the case of metric for a EIGRP or OSFP like protocol the second template argument could be the compound of a dozen or more different variable. Each taking a non-trival time to copy or recompute.
For ease of use I investigate the use a function object that accepts the third and fourth template to handle special cases and polymorphic classes that would fail to function or copy correctly. The goal to not force a user to rebuild their objects from scratch. This would require planning for virtual function to preform deep copies, or any number of other unknown oddites. The usefulness of the function object depends on how sanely a compiler can be depended on not generate a cascade of function calls.
More helpful I hope?
The C++11 standard doesn't say anything about how constexpr will be compiled down to machine instructions. The standard just says that expressions that are constexpr may be used in contexts where a compile time constant value is required. How any particular compiler chooses to translate that to executable code is an implementation issue.
Now in general, with optimizations turned on you can expect a reasonable compiler to not execute any code at runtime for many uses of constexpr but there aren't really any guarantees. I'm not really clear on what exactly you're asking about in your example so it's hard to give any specifics about your use case.
constexpr expressions are not special. For all intents and purposes, they're basically const unless the context they're used in is constexpr and all variables/functions are also constexpr. It is implementation defined how the compiler chooses to handle this. The Standard never deals with implementation details because it speaks in abstract terms.

Why isn't constexpr implied when applicable?

These should probably be in different questions, but they're related so...
Why do we need to write constexpr at all? Given a set of restrictions couldn't a compiler evaluate code to see if it satisfies the constexpr requirements, and treat it as constexpr if it does? As a purely documentation keyword I'm not sure it holds up because I can't think of a case where I (the user of someone else's constexpr function) should really care if it's run time or not.
Here's my logic: If it's an expensive function I think as a matter of good practice I should treat it as such regardless of whether I give it compile-time constant input or not. That might mean calling it during load time and saving off the result, instead of calling it during a critical point in the execution. The reason is because constexpr doesn't actually guarantee to me that it will not be executed in run time in the first place ā€” so perhaps a new/different mechanism should do that.
The constexpr restrictions seem to exclude many, if not most, functions from being compile-time evaluated which logically could be. I've read this is at least in part (or perhaps wholly?) to prevent infinite looping and hanging the compiler. But, if this is the reason, is it legitimate?
Shouldn't a compiler be able to compute if, for any given constexpr function with the given inputs used, it loops infinitely? This is not solving the halting problem for any input. The input to a constexpr function is compile time constant and finite, so the compiler only has to check for infinite looping for a finite set of input: the input actually used. It should be a regular compilation error if you write a compile-time infinite loop.
I asked a very similar question, Why do we need to mark functions as constexpr?
When I pressed Richard Smith, a Clang author, he explained:
The constexpr keyword does have utility.
It affects when a function template specialization is instantiated (constexpr function template specializations may need to be instantiated if they're called in unevaluated contexts; the same is not true for non-constexpr functions since a call to one can never be part of a constant expression). If we removed the meaning of the keyword, we'd have to instantiate a bunch more specializations early, just in case the call happens to be a constant expression.
It reduces compilation time, by limiting the set of function calls that implementations are required to try evaluating during translation. (This matters for contexts where implementations are required to try constant expression evaluation, but it's not an error if such evaluation fails -- in particular, the initializers of objects of static storage duration.)
This all didn't seem convincing at first, but if you work through the details, things do unravel without constexpr. A function need not be instantiated until it is ODR-used, which essentially means used at runtime. What is special about constexpr functions is that they can violate this rule and require instantiation anyway.
Function instantiation is a recursive procedure. Instantiating a function results in instantiation of the functions and classes it uses, regardless of the arguments to any particular call.
If something went wrong while instantiating this dependency tree (potentially at significant expense), it would be difficult to swallow the error. Furthermore, class template instantiation can have runtime side-effects.
Given an argument-dependent compile-time function call in a function signature, overload resolution may incur instantiation of function definitions merely auxiliary to the ones in the overload set, including the functions that don't even get called. Such instantiations may have side effects including ill-formedness and runtime behavior.
It's a corner case to be sure, but bad things can happen if you don't require people to opt-in to constexpr functions.
As for constexpr objects, certain types can produce core constant expressions which are usable in constant expression contexts without having been declared constexpr. But you don't really want the compiler to try evaluating every single expression at compile time. That's what constant propagation is for. On the other hand it seems pretty essential to document when something needs to happen at compile time.
[Note, I totally changed my answer]
To answer your second question, there are two cases for the compiler here:
The compiler has to be able to handle any arbitrary constexpr function(s). In this case you still have the halting problem because the set of inputs is all combinations of constexpr functions and calls to them.
The compiler can handle a finite set of constexpr function(s). In this case the compiler can in fact determine whether some programs will result in infinite loops, while other programs will be uncompilable (since they aren't in the set of valid inputs).
So presumably the restrictions are in place so that it satisfies case 2 for a reasonable amount of compiler effort.
There are both technical and ideological reasons behind this decision.
Not always do we want constexpr ourselves by default - it can take
too much compiling time. That's first. Just imagine you implemented
isPrime function and you have 100 calls with big constexpr
values passed in. I think you don't (in most cases) want to make
compiler compiling this for a couple of minutes longer because it
decided that you need those values in compile-time by itself. But if
it's exactly the case - specify constexpr modifier manually. And this adds the next point:
backward compatibility - it's unwise to assume that every possible C++98 program author who converted this program to C++11 wantsconstexpr.
The second point is that deciding if the function can be constexpr
would take compiling time by itself. And if it was trying to do that for every possible function it would take some additional time overhead. Even more, often compiler
couldn't decide if the given function can be constexpr at all, so
your first assumption is not correct.

Reduce C++ source by variable substitution and dead code truncation?

Suppose I have some template classes with Nontype parameters.
template <int hi, int wid>
class SomeThing {
...
}
I need to create a tool to reduce this source with given value of hi and wid, say, hi=2; wid=3. Sequentially, there might be some code becomes dead code, and the tool also needs to truncate them away. So, finally I expect to see a reduced source code as the output of the tool. Is there any known way to do this? A harder way may be to create my own c++ parser... sounds terrible even a simplified one.
I know there are tools like gcc-xml and clang which can parse it and give an easy-to-parse intermediate file. However, it looks like that it's not enough for me to regenerate c++ source file from that.
[EDIT]
A whole picture is to create a tool to generate source code from source code, with variable substitution and dead code truncation.
I'm not sure I quite understood your question, but would template specialization answers your needs?
template<>
class SomeThing<2, 3> {
//trimmed content
};
If you instantiate SomeThing with the value 2 and 3, the specialization will be chosen by the compiler and the generated executable will contain only the "truncated" content.
Edit:
Based on your edit, I suspect that you'd like to have a partial evaluator for C++, meaning a program which takes a program and some of its inputs, and generates a specialized version of the program where all that could be evaluated had been evaluated.
I'm not aware of any existing implementations for native C++; however, you can find partial evaluators for many functional languages, but also for Pascal and C. Some works have been done to create a partial evaluator for the .Net bytecode (MSIL), which could be used to partially evaluate C++/CLI. [Chepovsky et al. 2003]
The C++ template mechanism can be seen as a limited kind of partial evaluation, since the compiler generates code specialized (and potentially partially evaluated) with the template parameters. However, all this is performed by the compiler internally, there is no intermediary C++ source code that you could visualize. However, you can have a look at the generated assembly code, which gives you a good idea of the operations/evaluations/optimizations performed by the compiler during template instantiation.
There's no clean way to do this, as template code is generally Turing-complete.
As a very simple example, consider
template<int I>
class X : public X<I/2>
{
};
Now say that you want to reduce this for I==351. What exactly should be the base classes be? For real-world code you will need a full C++ compiler. Worse, you will also need a matching standard library implementation, and one that is fully representative of all compliant standard library implementations (!!)
Consider the following code:
template <int I>
class X : public std::vector<X<I/2> >
{
// Methods
};
Dead code elimination will depend on the implementation of std::vector. If your implementations differ, you can accidentily eliminate code that is in fact needed.

Whyever **not** declare a function to be `constexpr`?

Any function that consists of a return statement only could be declared
constexpr and thus will allow to be evaluated at compile time if all
arguments are constexpr and only constexpr functions are called in its body. Is there any reason not to declare any such function constexpr ?
Example:
constexpr int sum(int x, int y) { return x + y; }
constexpr i = 10;
static_assert(sum(i, 13) == 23, "sum correct");
Could anyone provide an example where declaring a function constexpr
would do any harm?
Some initial thoughts:
Even if there should be no good reason for ever declaring a function
not constexpr I could imagine that the constexpr keyword has a
transitional role: its absence in code that does not need compile-time
evaluations would allow compilers that do not implement compile-time
evaluations still to compile that code (but to fail reliably on code
that needs them as made explict by using constexpr).
But what I do not understand: if there should be no good reason for
ever declaring a function not constexpr, why is not every function
in the standard library declared constexpr? (You cannot argue
that it is not done yet because there was not sufficient time yet to
do it, because doing it for all is a no-brainer -- contrary to deciding for every single function if to make it constexpr or not.)
--- I am aware that N2976
deliberately not requires cstrs for many standard library types such
as the containers as this would be too limitating for possible
implementations. Lets exclude them from the argument and just wonder:
once a type in the standard library actually has a constexpr cstr, why is not every function operating on it declared constexpr?
In most cases you also cannot argue that you may prefer not to declare a function constexpr simply because you do not envisage any compile-time usage: because if others evtl. will use your code, they may see such a use that you do not. (But granted for type trait types and stuff alike, of course.)
So I guess there must be a good reason and a good example for deliberately not declaring a function constexpr?
(with "every function" I always mean: every function that meets the
requirements for being constexpr, i.e., is defined as a single
return statement, takes only arguments of types with constexpr
cstrs and calls only constexpr functions. Since C++14, much more is allowed in the body of such function: e.g., C++14 constexpr functions may use local variables and loops, so an even wider class of functions could be declared constexpr.)
The question Why does std::forward discard constexpr-ness? is a special case of this one.
Functions can only be declared constexpr if they obey the rules for constexpr --- no dynamic casts, no memory allocation, no calls to non-constexpr functions, etc.
Declaring a function in the standard library as constexpr requires that ALL implementations obey those rules.
Firstly, this requires checking for each function that it can be implemented as constexpr, which is a long job.
Secondly, this is a big constraint on the implementations, and will outlaw many debugging implementations. It is therefore only worth it if the benefits outweigh the costs, or the requirements are sufficiently tight that the implementation pretty much has to obey the constexpr rules anyway. Making this evaluation for each function is again a long job.
I think what you're referring to is called partial evaluation. What you're touching on is that some programs can be split into two parts - a piece that requires runtime information, and a piece that can be done without any runtime information - and that in theory you could just fully evaluate the part of the program that doesn't need any runtime information before you even start running the program. There are some programming languages that do this. For example, the D programming language has an interpreter built into the compiler that lets you execute code at compile-time, provided that it meets certain restrictions.
There are a few main challenges in getting partial evaluation working. First, it dramatically complicates the logic of the compiler because the compiler will need to have the ability to simulate all of the operations that you could put into an executable program at compile-time. This, in the worst case, requires you to have a full interpreter inside of the compiler, making a difficult problem (writing a good C++ compiler) and making it orders of magnitude harder to do.
I believe that the reason for the current specification about constexpr is simply to limit the complexity of compilers. The cases it's limited to are fairly simple to check. There's no need to implement loops in the compiler (which could cause a whole other slew of problems, like what happens if you get an infinite loop inside the compiler). It also avoids the compiler potentially having to evaluate statements that could cause segfaults at runtime, such as following a bad pointer.
Another consideration to keep in mind is that some functions have side-effects, such as reading from cin or opening a network connection. Functions like these fundamentally can't be optimized at compile-time, since doing so would require knowledge only available at runtime.
To summarize, there's no theoretical reason you couldn't partially evaluate C++ programs at compile-time. In fact, people do this all the time. Optimizing compilers, for example, are essentially programs that try to do this as much as possible. Template metaprogramming is one instance where C++ programmers try to execute code inside the compiler, and it's possible to do some great things with templates partially because the rules for templates form a functional language, which the compiler has an easier time implementing. Moreover, if you think of the tradeoff between compiler author hours and programming hours, template metaprogramming shows that if you're okay making programmers bend over backwards to get what they want, you can build a pretty weak language (the template system) and keep the language complexity simple. (I say "weak" as in "not particularly expressive," not "weak" in the computability theory sense).
Hope this helps!
If the function has side effects, you would not want to mark it constexpr. Example
I can't get any unexpected results from that, actually it looks like gcc 4.5.1 just ignores constexpr

reuse function logic in a const expression

I think my question is, is there anyway to emulate the behaviour that we'll gain from C++0x's constexpr keyword with the current C++ standard (that is if I understand what constexpr is supposed to do correctly).
To be more clear, there are times when it is useful to calculate a value at compile time but it is also useful to be able to calculate it at runtime too, for e.g. if we want to calculate powers, we could use the code below.
template<int X, unsigned int Y>
struct xPowerY_const {
static const int value = X*xPowerY_const<X,Y-1>::value;
};
template<int X>
struct xPowerY_const<X, 1> {
static const int value = X;
};
int xPowerY(int x, unsigned int y) {
return (y==1) ? x : x*xPowerY(x,y-1);
}
This is a simple example but in more complicated cases being able to reuse the code would be helpful. Even if, for runtime performance, the recursive nature of the function is suboptimal and a better algorithm could be devised it would be useful for testing the logic if the templated version could be expressed in a function, as I can't see a reasonable method of testing the validity of the constant template method in a wide range of cases (although perhaps there is one and i just can't see it, and perhaps that's another question).
Thanks.
Edit
Forgot to mention, I don't want to #define
Edit2 Also my code above is wrong, it doesn't deal with x^0, but that doesn't affect the question.
Template metaprogramming implements logic in an entirely different (and incompatible) way from "normal" C++ code. You're not defining a function, you're defining a type. It just happens that the type has a value associated with it, which is built up from a combination of other types.
Because the templates define types, there is no program logic involved. The logic is simply a side effect of the compiler trying to resolve relationships between the templated types. There really isn't any way to automatically extract the high level logic from a template "program" into a function.
FWIW, template metaprogramming wasn't even a glimmer in Bjarne's eye when templates were first implemented. They were actually discovered later on in the language's life by users of the language. It's an "unintended" side-effect of the type system that just happened to become very popular. It's precisely because of this discovery that new features are being added to the language to more thoroughly support the idioms that have evolved.