I am programming with C++11 and was wondering if there is a way to generate some code during execution.
For example instead of writing:
void b(int i){i+1}
void c(int i){i-1}
if(true) b()
else{ c() }
would there be a more straightforward way to say if true, then replace all + with - ?
Thank you and sorry if this question is stupid..
C++ has no native facilities for runtime code generation. You could of course invoke a C++ compiler from your program, then dynamically load the resulting binary, and call code from it, but I doubt this is the best solution to your problem.
If you are worried about repeatedly checking the condition, you shouldn't be. Modern CPUs will likely deal with this very well, even in a tight loop, due to branch prediction.
Last, if you really want to more dynamically alter the code path you take, you could use function pointers and/or polymorphism and/or lambdas.
An example with functions
typedef void (pFun*)(int); // pointer to function taking int, returning void
void b(int i){i+1}
void c(int i){i-1}
...
pFun d = cond ? b : c; // based on condition, select function b or c
...
pFun(i); // calls either b or c, effectively selecting + or -
An example with polymorphism
class Operator
{
public:
Operator() {}
virtual ~Operator() {}
virtual void doIt(int i) = 0;
};
class Add : public Operator
{
public:
virtual void doIt(int i) { i+1; }
};
class Sub : public Operator
{
public:
virtual void doIt(int i) { i-1; }
};
...
Operator *pOp = cond ? new Add() : new Sub();
...
pOp->doIt(i);
...
delete pOp;
Here, I have defined a base class with the doIt pure virtual function. The two child classes override the doIt() function to do different things. pOp will then point at either an Add or a Sub instance depending on cond, so when pOp->doIt() is called, the appropriate implementation of your operator is used. Under the covers, this does essentially what I outlined in the above example with function pointers, so choosing one over the other is largely a matter of style and/or other design constrains. They should both perform just as well.
An example with lambdas
This is basically the same as the first example using function pointers, but done in a more C++11 way using lambdas (and it is more concise).
auto d = cond ? [](int i) { i+1; }
: [](int i) { i-1; };
...
d(i);
Alternatively, you may prefer to have the condition inside the body of the lambda, for example
auto d = [&](int i) { cond ? i+1 : i-1; }
...
d(i);
C++ does not have runtime code generation since it's a compiled language.
In this case, you could put the sign into a variable (to be used with multiple variables.)
E.g.
int sign = (true ? 1 : -1);
result2 += sign;
result1 += sign;
Not necessarily a solution for your problem, but you could use
a template, instantiated on one of the operators in <functional>:
template <typename Op>
int
func( int i )
{
return Op()( i, 1 );
}
In your calling function, you would then do something like:
int (*f)( int i ) = condition ? &func<std::plus> : &func<std::minus>;
// ...
i = f( i );
It's possible to use lambdas, which may be preferable, but you can't use
the conditional operator in this case. (Every lambda has a unique type,
and the second and third operatands of the conditional operator must
have the same type.) So it becomes a bit more verbose:
int (*f)( int i );
if ( condition ) {
f = []( int i ) { return i + 1; }
} else {
f = []( int i ) { return i - 1; }
}
This will only work if there is no capture in the lambdas; when there is
no capture, the lambda not only generates an instance of a class with
a unique type, but also a function. Although not being able to use the
conditional operator makes this more verbose than necessary, it is still
probably simpler than having to define a function outside of the class,
unless that function can be implemented as a template, as in my first
example. (I'm assuming that your actual case may be significantly more
complicated than the example you've posted.)
EDIT:
Re lambdas, I tried:
auto f = c ? []( int i ) { return i + 1; } : []( int i ) { return i - 1; };
just out of curiosity. MSC++ gave me the expected error
message:
no conversion from 'someFunc::<lambda_21edbc86aa2c32f897f801ab50700d74>' to 'someFunc::<lambda_0dff34d4a518b95e95f7980e6ff211c5>'
but g++ compiled it without complaining, typeid(f) gave "PFiiI",
which I think is a pointer to a function. In this case, I'm pretty sure
that MSC++ is right: the standard says that each of the lambdas has
a unique type, and that each has a conversion operator to (in this
case) an int (*)( int ) (so both can be converted to the same
type—this is why the version with the if works). But the
specification of the conditional operator requires that either the
second operand can be converted to the type of the third, or vice versa,
but the results must be the type of one of the operands; it cannot be
a third type to which both are converted.
Related
Sometimes for algebraic types it is convenient to have a constructor that takes a literal value 0 to denote the neutral element, or 1 to denote the multiplicative identity element, even if the underlying type is not an integer.
The problem is that it is not obvious how to convince the compiler only to accept, 0 or 1 without accepting any other integer.
Is there a way to do this in C++14 or beyond, for example combining literals, constexpr or static_assert?
Let me illustrate with a free function (although the idea is to use the technique for a constructor that take a single argument. Contructors cannot take template parameters either).
A function that accepts zero only could be written in this way:
constexpr void f_zero(int zero){assert(zero==0); ...}
The problem is that, this could only fail at runtime. I could write f_zero(2) or even f_zero(2.2) and the program will still compile.
The second case is easy to remove, by using enable_if for example
template<class Int, typename = std::enable_if_t<std::is_same<Int, int>{}> >
constexpr void g_zero(Int zero){assert(zero==0);}
This still has the problem that I can pass any integer (and it only fails in debug mode).
In C++ pre 11 one had the ability to do this trick to only accept a literal zero.
struct zero_tag_{};
using zero_t = zero_tag_***;
constexpr void h_zero(zero_t zero){assert(zero==nullptr);}
This actually allowed one to be 99% there, except for very ugly error messages.
Because, basically (modulo Maquevelian use), the only argument accepted would be h_zero(0).
This is situation of affairs is illustrated here https://godbolt.org/z/wSD9ri .
I saw this technique being used in the Boost.Units library.
1) Can one do better now using new features of C++?
The reason I ask is because with the literal 1 the above technique fails completely.
2) Is there an equivalent trick that can be applied to the literal 1 case? (ideally as a separate function).
I could imagine that one can invent a non-standard long long literal _c that creates an instance of std::integral_constant<int, 0> or std::integral_constant<int, 1> and then make the function take these types. However the resulting syntax will be worst for the 0 case. Perhaps there is something simpler.
f(0_c);
f(1_c);
EDIT: I should have mentioned that since f(0) and f(1) are potentially completely separate functions then ideally they should call different functions (or overloads).
In C++20 you can use the consteval keyword to force compile time evaluation. With that you could create a struct, which has a consteval constructor and use that as an argument to a function. Like this:
struct S
{
private:
int x;
public:
S() = delete;
consteval S(int _x)
: x(_x)
{
if (x != 0 && x != 1)
{
// this will trigger a compile error,
// because the allocation is never deleted
// static_assert(_x == 0 || _x == 1); didn't work...
new int{0};
}
}
int get_x() const noexcept
{
return x;
}
};
void func(S s)
{
// use s.get_x() to decide control flow
}
int main()
{
func(0); // this works
func(1); // this also works
func(2); // this is a compile error
}
Here's a godbolt example as well.
Edit:
Apperently clang 10 does not give an error as seen here, but clang (trunk) on godbolt does.
You can get this by passing the 0 or 1 as a template argument like so:
template <int value, typename = std::enable_if_t<value == 0 | value == 1>>
void f() {
// Do something with value
}
The function would then be called like: f<0>(). I don't believe the same thing can be done for constructors (because you can't explicitly set template parameters for constructors), but you could make the constructor(s) private and have static wrapper functions which can be given template parameters perform the check:
class A {
private:
A(int value) { ... }
public:
template <int value, typename = std::enable_if_t<value == 0 || value == 1>>
static A make_A() {
return A(value);
}
};
Objects of type A would be created with A::make_A<0>().
Well... you have tagged C++17, so you can use if constexpr.
So you can define a literal type when 0_x is a std::integral_constant<int, 0> value, when 1_x is a std::integral_constant<int, 1> and when 2_x (and other values) gives a compilation error.
By example
template <char ... Chs>
auto operator "" _x()
{
using t0 = std::integer_sequence<char, '0'>;
using t1 = std::integer_sequence<char, '1'>;
using tx = std::integer_sequence<char, Chs...>;
if constexpr ( std::is_same_v<t0, tx> )
return std::integral_constant<int, 0>{};
else if constexpr ( std::is_same_v<t1, tx> )
return std::integral_constant<int, 1>{};
}
int main ()
{
auto x0 = 0_x;
auto x1 = 1_x;
//auto x2 = 2_x; // compilation error
static_assert( std::is_same_v<decltype(x0),
std::integral_constant<int, 0>> );
static_assert( std::is_same_v<decltype(x1),
std::integral_constant<int, 1>> );
}
Now your f() function can be
template <int X, std::enable_if_t<(X == 0) || (X == 1), bool> = true>
void f (std::integral_constant<int, X> const &)
{
// do something with X
}
and you can call it as follows
f(0_x);
f(1_x);
For the case of Ada, you can define a subtype, a new type, or a derived type that is constrained only for the values of Integer 0 and 1.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure two_value is
-- You can use any one of the following 3 declarations. Just comment out other two.
--subtype zero_or_one is Integer range 0 .. 1; -- subtype of Integer.
--type zero_or_one is range 0 .. 1; -- new type.
type zero_or_one is new Integer range 0 .. 1; -- derived type from Integer.
function get_val (val_1 : in zero_or_one) return Integer;
function get_val (val_1 : in zero_or_one) return Integer is
begin
if (val_1 = 0) then
return 0;
else
return 1;
end if;
end get_val;
begin
Put_Line("Demonstrate the use of only two values");
Put_Line(Integer'Image(get_val(0)));
Put_Line(Integer'Image(get_val(1)));
Put_Line(Integer'Image(get_val(2)));
end two_value;
upon compiling you get the following warning message, although compiles successfully :
>gnatmake two_value.adb
gcc -c two_value.adb
two_value.adb:29:40: warning: value not in range of type "zero_or_one" defined at line 8
two_value.adb:29:40: warning: "Constraint_Error" will be raised at run time
gnatbind -x two_value.ali
gnatlink two_value.ali
And executing it gives the runtime error as specified by the compiler
>two_value.exe
Demonstrate the use of only two values
0
1
raised CONSTRAINT_ERROR : two_value.adb:29 range check failed
So, basically you can constrain the values by defining the new types, derived types or subtypes, you don't need to include the code to check the range, but based on your data type the compiler will automatically warn you.
This isn't a modern solution, but adding on to Zach Peltzer's solution, you can keep your syntax if you use macros...
template <int value, typename = std::enable_if_t<value == 0 | value == 1>>
constexpr int f_impl() {
// Do something with value
return 1;
}
#define f(x) f_impl<x>()
int main() {
f(0); //ok
f(1); //ok
f(2); //compile time error
}
Though, with the constructor problem you could just make the class templated instead of trying to have a templated constructor
template<int value, typename = std::enable_if_t<value == 0 | value == 1>>
class A {
public:
A() {
//do stuff
}
};
int main() {
A<0> a0;
auto a1 = A<1>();
// auto a2 = A<2>(); //fails!
}
The best solution to accept literal 0 that I've found to date is to use std::nullptr_t as the function's input:
struct math_object
{
real x,y,z;
math_object(std::nullptr_t) : x(0), y(0), z(0) {}
};
This has conversion advantages over some of the other solutions. For example, it allows syntax such as.. void MyFunc(const math_object &obj=0); I've been using this for years, and haven't found any trouble. However, I do not have a similar solution for literal 1. For that, I created a construct::id structure that has a global IDENTITY variable.
There's a basic problem. How can you do that in the compiler to be done for a parameter, and at the same time be efficient? Well, what do you need exactly?
That is included in strong typed languages like Pascal, or Ada. The enumerated types have only a couple of values, and the types are normally checked at development, but otherwise, the checks are eliminated by some compiler option at runtime, because just everything goes well.
A function interface is a contract. It is a contract between a seller (the writer of the function) and a buyer (the user of that function). There's even an arbiter, which is the programming language, that can act upon if someone tries to cheat the contract. But at the end, the program is being run in a machine that's open to make arbitraryness like modifying the set of enumerated values and put in the place a completely (and not permitted value).
The problem comes also with separate compilation. Separate compilation has its drawbacks, as it must face a compilation, without having to recheck and retest all previous compilations you have made. Once a compilation is finished, everything you have put in the code is there. If you want the code to be efficient, then the tests are superfluous, because caller and implementer both cope with the contract, but if you want to catch a lyer, then you have to include the test code. And then, it is better to do once for all cases, or is it better to let the programmer decide when and when not we want to catch a lyer?
The problem with C (and by legacy with C++) is that they were inspired by very good programmers, that didn't mistakes, and that have to run their software in big and slow machines. They decided to make both languages (the second was for interoperability purposes) weak typed... and so they are. Have you tried to program in Ada? or Modula-2? You'll see that, over the time, the strong typing thing is more academic than otherwise, and finally what you want, as a professional, is to have the freedom to say: now I want to be safe (and include test code), and now I know what I'm doing (and please be most efficient as you can)
Conclusion
The conclussion is that you are free to select the language, to select the compiler, and to relax the rules. The compilers have the possibility to allow you that. And you have to cope with it, or invent (this is something that todays happens almost each week) your own programming language.
This is the answer to my question, based on #IlCapitano answer for a wrapper class.
This wrapper class can be made private an used only on the construction.
class Matrix {
struct ZeroOROne {
/*implicit*/ consteval ZeroOROne(int n) : val_{n} {
if (n != 0 and n != 1) {throw;} // throw can produce an error at compile time
}
int val_;
};
public:
constexpr Matrix(ZeroOROne _0_or_1) {
if(_0_or_1.val_ == 0) { // this cannot be if constexpr, but that is ok
a00 = a01 = a10 = a11 = 0.0;
new int{0}; // allocation could is ok here
} else {
a00 = a11 = 1.0;
a10 = a01 = 0.0;
new int{0}; // allocation could is ok here
}
}
double a00; double a01;
double a10; double a11;
};
In this way, only Matrix A(0) or Matrix A(1) are allowed.
(Although it works with constant variables as well, but that is ok.)
int main() {
// ZeroOROne(0);
// ZeroOROne(1);
// ZeroOROne(2); // compilation error
Matrix A(0);
Matrix B(1);
// Matrix C(2); // compilation error
int const d = 0; // this works because the compiler can "see" the 0.
Matrix D(d);
constexpr int e = 0;
Matrix E(e);
// int f = 0;
// Matrix F(f); // compile error
return B.a00;
}
Here it is shown that the "runtime" if in the constructor is not a problem and can be elided by the compiler: https://godbolt.org/z/hd6TWY6qW
The solution needs C++20 and it works in recent version of GCC and clang.
I have a member function with two arguments. Both are pointers to complex objects. When called, the function performs some non-trivial computation and then returns an integer. Like this:
struct Fooer {
int foo(const A* a, const B* b);
};
The returned integer is always the same if foo() is given the same two arguments. This function is pretty heavily used, so it would make sense to memoize its result. Normally, some lookup table with the key being the pair of pointers would suffice. However, I'm in the unique position where I know all the call sites and I know that any given call site will always use the same pair of parameters during execution. This could greatly speed up memoization if only I could pass in a third parameter, a unique integer that is basically the cache hint:
struct Fooer {
int foo(const A* a, const B* b, int pos) {
if (cached_[pos] > 0) return cached_[pos];
cached_[pos] = /* Heavy computation. */ + 1;
return cached_[pos];
}
std::vector<int> cached_;
};
What I'm looking for is a mechanism to easily generate this 'cache hint'. But nothing comes to mind. For now, I'm manually adding this parameter to the call sites of foo(), but it's obviously ugly and fragile. The function is really heavily used so it's worth this kind of optimization, in case you're wondering.
More generally, I'd like to have some kind of 'thunk' at each call site that performs the heavy lifting the first time is called, then just returns the pre-computed integer.
Note that foo() is a member function so that different instances of Fooer should have different caches.
Would this approach help you?
struct Fooer {
using CacheMap = std::map<std::pair<const A*, const B*>, int>;
std::map<int, CacheMap> lineCache;
int foo(const A* a, const B* b, int line) {
const auto key = std::make_pair(a,b);
if (linecache.count(line) > 0) {
CacheMap& cacheMap = lineCache[line];
if(cacheMap.count(key)) return cacheMap[key];
}
lineCache[line][key] = /* Heavy computation. */ + 1;
return cacheMap[key];
}
};
// Calling
foo(a, b, __LINE__)
See _ReturnAddress or any alternatives for yours compiler. Maybe you can use it in your project. Obviously, if it work for you, than just create map caller-result.
I've two class named 'Expression' and 'BinExp' as following codes:
class Expression
{
public:
virtual BinExp* IsBinaryExp() { return NULL; }
};
class BinExp : public Expression
{
public:
virtual BinExp* IsBinaryExp() { return this; }
};
As example, I've a pointer variable type of Expression* but initialized as new BinExp and send as argument to a analyse function as following code:
int main()
{
Expression* e = new BinExp;
analyse(e);
}
Inside the analyse function, I need to know whether the e is pointer to Expression type or BinExp type. In my hand, there is three way to do this.
First:
BinExp* be = e->IsBinaryExp();
if ( be )
{
printf("Yes, `e` is a binary expression\n");
}
Second:
BinExp* be = dynamic_cast<BinExp*>(e);
if ( be )
{
printf("Yes, `e` is a binary expression\n");
}
And the third:
if ( typeid(*e) == typeid(BinExp) )
{
BinExp* be = e->IsBinaryExp(); // or dynamic_cast<BinExp*>(e);
printf("Yes, `e` is a binary expression\n");
}
But I want to know which of those ways ( or any other ) will be more efficient and effective when I need to perform the checking frequently inside a loop where performance is a matter. Any kind of suggestion I will appreciate.
The fastest way would be to keep a member variable , say an enum , then define in the base class a inline getter, then you can compare if the result is what you expect.
Sample (uncompiled, some errors might occur) :
enum eExpTypes {
ET_UNDEFINED,
ET_BINARY
}
class Expresion
{
protected:
eExpTypes myType;
public:
Expresion(): myType(ET_UNDEFINED){};
inline eExpTypes getType(){return myType;};
}
class BinExpresion : public Expresion
{
public:
BinExpresion():myType(ET_BINARY){};
}
Performance gain :
you will take out two indiections : from pointer to vfptable , from vfptable to function
your class size will be less if the type function is the only virtual function
Dynamic cast is usually slower then making your own type check mechanism, so in case of your 3 examples the first one should be the fastest.
The fastest will be:
e->printIsBinExp();
Where you make that virtual method that either prints or is a noop.
I'm only partially joking. The point of virtual methods is to encapsulate different types' handling of a particular method - not to write a program to just do a runtime switch on what the different runtime types could be.
Suppose the dynamic_cast was fastest. Would you then write:
if (BinExp* be = dynamic_cast<BinExp*>(e)) {
// ...
}
else if (UnExp* ue = dynamic_cast<UnExp*>(e)) {
// ...
}
else if (TernExp* te = dynamic_cast<TernExp*>(e)) {
// ...
}
Hopefully not. That code is going to be very brittle. You'll definitely want to come up with a design such that:
e->eval();
just does the right thing as a single virtual call.
Number 3 is the most elegant.
To find out if or which one is the most efficient, some simple code can be used to measure execution time of each case...
#include <iostream>
#include <chrono>
/*
Case
*/
int main()
{
const clock_t begin_time = clock();
// Case
std::cout << float(clock() - begin_time) / CLOCKS_PER_SEC;
system("pause");
return 0;
}
I'm doing a linear genetic programming project, where programs are bred and evolved by means of natural evolution mechanisms. Their "DNA" is basically a container (I've used arrays and vectors successfully) which contain function pointers to a set of functions available.
Now, for simple problems, such as mathematical problems, I could use one type-defined function pointer which could point to functions that all return a double and all take as parameters two doubles.
Unfortunately this is not very practical. I need to be able to have a container which can have different sorts of function pointers, say a function pointer to a function which takes no arguments, or a function which takes one argument, or a function which returns something, etc (you get the idea)...
Is there any way to do this using any kind of container ?
Could I do that using a container which contains polymorphic classes, which in their turn have various kinds of function pointers?
I hope someone can direct me towards a solution because redesigning everything I've done so far is going to be painful.
A typical idea for virtual machines is to have a separate stack that is used for argument and return value passing.
Your functions can still all be of type void fn(void), but you do argument passing and returning manually.
You can do something like this:
class ArgumentStack {
public:
void push(double ret_val) { m_stack.push_back(ret_val); }
double pop() {
double arg = m_stack.back();
m_stack.pop_back();
return arg;
}
private:
std::vector<double> m_stack;
};
ArgumentStack stack;
...so a function could look like this:
// Multiplies two doubles on top of the stack.
void multiply() {
// Read arguments.
double a1 = stack.pop();
double a2 = stack.pop();
// Multiply!
double result = a1 * a2;
// Return the result by putting it on the stack.
stack.push(result);
}
This can be used in this way:
// Calculate 4 * 2.
stack.push(4);
stack.push(2);
multiply();
printf("2 * 4 = %f\n", stack.pop());
Do you follow?
You cannot put a polymorphic function in a class, since functions that take (or return) different things cannot be used in the same way (with the same interface), which is something required by polymorphism.
The idea of having a class providing a virtual function for any possible function type you need would work, but (without knowing anything about your problem!) its usage feels weird to me: what functions would a derived class override? Aren't your functions uncorrelated?
If your functions are uncorrelated (if there's no reason why you should group them as members of the same class, or if they would be static function since they don't need member variables) you should opt for something else... If you pick your functions at random you could just have several different containers, one for function type, and just pick a container at random, and then a function within it.
Could you make some examples of what your functions do?
What you mentioned itself can be implemented probably by a container of
std::function or discriminated union like Boost::variant.
For example:
#include <functional>
#include <cstdio>
#include <iostream>
struct F {
virtual ~F() {}
};
template< class Return, class Param = void >
struct Func : F {
std::function< Return( Param ) > f;
Func( std::function< Return( Param ) > const& f ) : f( f ) {}
Return operator()( Param const& x ) const { return f( x ); }
};
template< class Return >
struct Func< Return, void > : F {
std::function< Return() > f;
Func( std::function< Return() > const& f ) : f( f ) {}
Return operator()() const { return f(); }
};
static void f_void_void( void ) { puts("void"); }
static int f_int_int( int x ) { return x; }
int main()
{
F *f[] = {
new Func< void >( f_void_void ),
new Func< int, int >( f_int_int ),
};
for ( F **a = f, **e = f + 2; a != e; ++ a ) {
if ( auto p = dynamic_cast< Func< void >* >( *a ) ) {
(*p)();
}
else if ( auto p = dynamic_cast< Func< int, int >* >( *a ) ) {
std::cout<< (*p)( 1 ) <<'\n';
}
}
}
But I'm not sure this is really what you want...
What do you think about Alf P. Steinbach's comment?
This sort of thing is possible with a bit of work. First it's important to understand why something simpler is not possible: in C/C++, the exact mechanism by which arguments are passed to functions and how return values are obtained from the function depends on the types (and sizes) of the arguments. This is defined in the application binary interface (ABI) which is a set of conventions that allow C++ code compiled by different compilers to interoperate. The language also specifies a bunch of implicit type conversions that occur at the call site. So the short and simple answer is that in C/C++ the compiler cannot emit machine code for a call to a function whose signature is not known at compile time.
Now, you can of course implement something like Javascript or Python in C++, where all values (relevant to these functions) are typed dynamically. You can have a base "Value" class that can be an integer, float, string, tuples, lists, maps, etc. You could use std::variant, but in my opinion this is actually syntactically cumbersome and you're better of doing it yourself:
enum class Type {integer, real, str, tuple, map};
struct Value
{
// Returns the type of this value.
virtual Type type() const = 0;
// Put any generic interfaces you want to have across all Value types here.
};
struct Integer: Value
{
int value;
Type type() const override { return Type::integer; }
};
struct String: Value
{
std::string value;
Type type() const override { return Type::str; }
};
struct Tuple: Value
{
std::vector<Value*> value;
Type type() const override { return Type::tuple; };
}
// etc. for whatever types are interesting to you.
Now you can define a function as anything that takes a single Value* and returns a single Value*. Multiple input or output arguments can be passed in as a Tuple, or a Map:
using Function = Value* (*)(Value*);
All your function implementations will need to get the type and do something appropriate with the argument:
Value* increment(Value* x)
{
switch (x->type())
{
Type::integer:
return new Integer(((Integer*) x)->value + 1);
Type::real:
return new Real(((Real*) x)->value + 1.0);
default:
throw TypeError("expected an integer or real argument.")
}
}
increment is now compatible with the Function type and can be stored in mFuncs. You can now call a function of unknown type on arguments of unknown type and you will get an exception if the arguments don't match, or a result of some unknown type if the arguments are compatible.
Most probably you will want to store the function signature as something you can introspect, i.e. dynamically figure out the number and type of arguments that a Function takes. In this case you can make a base Function class with the necessary introspection functions and provide it an operator () to make it look something like calling a regular function. Then you would derive and implement Function as needed.
This is a sketch, but hopefully contains enough pointers to show the way. There are also more type-safe ways to write this code (I like C-style casts when I've already checked the type, but some people might insist you should use dynamic_cast instead), but I figured that is not the point of this question. You will also have to figure out how Value* objects lifetime is managed and that is an entirely different discussion.
Suppose you have a function, and you call it a lot of times, every time the function return a big object. I've optimized the problem using a functor that return void, and store the returning value in a public member:
#include <vector>
const int N = 100;
std::vector<double> fun(const std::vector<double> & v, const int n)
{
std::vector<double> output = v;
output[n] *= output[n];
return output;
}
class F
{
public:
F() : output(N) {};
std::vector<double> output;
void operator()(const std::vector<double> & v, const int n)
{
output = v;
output[n] *= n;
}
};
int main()
{
std::vector<double> start(N,10.);
std::vector<double> end(N);
double a;
// first solution
for (unsigned long int i = 0; i != 10000000; ++i)
a = fun(start, 2)[3];
// second solution
F f;
for (unsigned long int i = 0; i != 10000000; ++i)
{
f(start, 2);
a = f.output[3];
}
}
Yes, I can use inline or optimize in an other way this problem, but here I want to stress on this problem: with the functor I declare and construct the output variable output only one time, using the function I do that every time it is called. The second solution is two time faster than the first with g++ -O1 or g++ -O2. What do you think about it, is it an ugly optimization?
Edit:
to clarify my aim. I have to evaluate the function >10M times, but I need the output only few random times. It's important that the input is not changed, in fact I declared it as a const reference. In this example the input is always the same, but in real world the input change and it is function of the previous output of the function.
More common scenario is to create object with reserved large enough size outside the function and pass large object to the function by pointer or by reference. You could reuse this object on several calls to your function. Thus you could reduce continual memory allocation.
In both cases you are allocating new vector many many times.
What you should do is to pass both input and output objects to your class/function:
void fun(const std::vector<double> & in, const int n, std::vector<double> & out)
{
out[n] *= in[n];
}
this way you separate your logic from the algorithm. You'll have to create a new std::vector once and pass it to the function as many time as you want. Notice that there's unnecessary no copy/allocation made.
p.s. it's been awhile since I did c++. It may not compile right away.
It's not an ugly optimization. It's actually a fairly decent one.
I would, however, hide output and make an operator[] member to access its members. Why? Because you just might be able to perform a lazy evaluation optimization by moving all the math to that function, thus only doing that math when the client requests that value. Until the user asks for it, why do it if you don't need to?
Edit:
Just checked the standard. Behavior of the assignment operator is based on insert(). Notes for that function state that an allocation occurs if new size exceeds current capacity. Of course this does not seem to explicitly disallow an implementation from reallocating even if otherwise...I'm pretty sure you'll find none that do and I'm sure the standard says something about it somewhere else. Thus you've improved speed by removing allocation calls.
You should still hide the internal vector. You'll have more chance to change implementation if you use encapsulation. You could also return a reference (maybe const) to the vector from the function and retain the original syntax.
I played with this a bit, and came up with the code below. I keep thinking there's a better way to do this, but it's escaping me for now.
The key differences:
I'm allergic to public member variables, so I made output private, and put getters around it.
Having the operator return void isn't necessary for the optimization, so I have it return the value as a const reference so we can preserve return value semantics.
I took a stab at generalizing the approach into a templated base class, so you can then define derived classes for a particular return type, and not re-define the plumbing. This assumes the object you want to create takes a one-arg constructor, and the function you want to call takes in one additional argument. I think you'd have to define other templates if this varies.
Enjoy...
#include <vector>
template<typename T, typename ConstructArg, typename FuncArg>
class ReturnT
{
public:
ReturnT(ConstructArg arg): output(arg){}
virtual ~ReturnT() {}
const T& operator()(const T& in, FuncArg arg)
{
output = in;
this->doOp(arg);
return this->getOutput();
}
const T& getOutput() const {return output;}
protected:
T& getOutput() {return output;}
private:
virtual void doOp(FuncArg arg) = 0;
T output;
};
class F : public ReturnT<std::vector<double>, std::size_t, const int>
{
public:
F(std::size_t size) : ReturnT<std::vector<double>, std::size_t, const int>(size) {}
private:
virtual void doOp(const int n)
{
this->getOutput()[n] *= n;
}
};
int main()
{
const int N = 100;
std::vector<double> start(N,10.);
double a;
// second solution
F f(N);
for (unsigned long int i = 0; i != 10000000; ++i)
{
a = f(start, 2)[3];
}
}
It seems quite strange(I mean the need for optimization at all) - I think that a decent compiler should perform return value optimization in such cases. Maybe all you need is to enable it.