size of a static vector - c++

I am using a static vector inside a member function and pushing back values into that vector;
but the size of vector is only 1 for three function calls.
I am not sure how to make MVCE for this as in MVCE it is working fine for me too, so the problem is obviously some other part of code.
I just want to know or have an idea under which circumstances would my static vector give me such results.
class X
{
//...
};
template <typename T>
void test(T a)
{
std::cout<<"Function called \n";
static std::vector<X> vec;
std::lock_guard<std::mutex> lock(mx);
//Doing something else with T
X obj;
vec.push_back(obj);
std::cout<<"no of elements in vec is "<<vec.size()<<"\n";
}
The output coming is
Function called
no of elements in vec is 1
Function called
no of elements in vec is 1
Function called
no of elements in vec is 1
The member function is called from the CPPREST http_client request call.

Note that the template instantiations with different type are irrelevant. It means if you called test() three time with different type T, then three irrelevant test() will be instantiated, with 3 diffrent instances of vec. That's why you're getting the result that their size are all 1.

Your request call probably looks similar to this
int i = 1;
float f = 2.5;
char c = 'A';
test(i);
test(f);
test(c);
If you add
test(i);
Then vec.size() for test(int) will be 2
While vec.size() for test(float) and test(char) will stay 1.
You can read more about the behavior of static variables in templates here http://www.geeksforgeeks.org/templates-and-static-variables-in-c/

Related

C++ How to cache a variable of template type T in a class?

Suppose that I have a Foo class like this, and I need many instances of it.
class Foo {
public:
Pool* bars; // a global list of bars, each may have a different type
template<typename T>
T& AddBar(int x) {
return bars->emplace<T>(x);
}
template<typename T>
T& GetBar() {
return bars->get<T>(); // a very slow function
}
}
All the instances of Foo share the same pool of bars, which contains many bars of possibly different types. For example, bars may be a list of bars {A bar1, B bar2, A bar3, C bar4} where ABC are some class types, but each Foo foo instance can only have one bar of a specific type, e.g., a foo instance cannot have two bars of type A.
Given an instance Foo foo, I can get a specific type of bar using foo.GetBar<A>(), foo.GetBar<B>(), etc, but calling the bars->get<T>() function is slow and expensive. Therefore, I'm thinking of caching the result of GetBar() so that subsequent calls can return immediately without querying the pool again.
Now this is what I came up with: I created a static variable inside the member function to store the value of bar, it is only initialized and assigned value once.
template<typename T>
T& GetBar() {
static T bar {};
if (bar == T {}) {
bar = bars->get<T>(); // a very slow function
}
return bar;
}
The problem is that, using the static keyword, this variable is now shared across all instances of Foo. If I try to get a bar of type A from different instances, they would return the same result.
Foo foo1;
Foo foo2;
foo1.AddBar<A>(1);
foo2.AddBar<A>(2);
foo1.GetBar<A>(); // returns a bar (type = A, value = 1)
foo2.GetBar<A>(); // returns the same bar with value 1, not 2
How can I cache every bar of type T inside the class and prevent it from being shared by other instances? I don't know how to store generic types as member variables, besides, storing each type T of bar can be a huge mess.
Edit: I know it'd be much easier to cache the result outside the class, on the caller's side. I'm just curious if there's an elegant way of caching inside the class.
Edit2: bars is a pointer to a registry pool, whose type is a complicated data structure, not a raw list or array. To clarify, I'm using the EnTT library to integrate entity-component-system into my application, but not sure how the pool is maintained internally in details.
Edit3: if you wonder what ABCs are, conceptually, these types are not known at compile time. but need to be determined at runtime. In fact, they are just many other class types I implemented, so I can also hardcode them into the Foo class, in which case I probably should use the factory pattern along with a scripting language for automatic code generation, but that would beat the purpose of using generics in the first place.
While writing a mockup, with the idea of n. 1.8e9-where's-my-share m., for your "complicated registry pool" I wrote the actual could be implementation of Foo. I left in there Foo only to also give some suggestions. If you want so have more than one variable of one type you would have to change the value type of the map of course, like from std::any to std::vector<std::any>. Otherwise please clarify your question more.
#include <iostream>
#include <string>
#include <map>
#include <any>
struct Pool {
template<typename T>
void emplace(T x) {
this->elements_.insert_or_assign(typeid(T).hash_code(), std::make_any<T>(x));
}
template<typename T>
T& get() {
return std::any_cast<T&>(elements_.at(typeid(T).hash_code()));
}
private:
std::map<std::size_t, std::any> elements_;
};
class Foo {
public:
Foo(Pool& pool): bars_(pool) {}
void AddBar(int x) {
return bars_.emplace<int>(x);
}
template<typename T>
T& GetBar() {
return bars_.get<T>(); // a very slow function
}
private:
Pool& bars_;
};
int main(){
Pool pool;
pool.emplace(4.3); pool.emplace(std::string("a value"));
Foo foo1(pool);
foo1.AddBar(3);
std::cout << foo1.GetBar<int>() << "\n";
}
All ECS implementations abandon static type safety somewhere deep under their hood, although they can hide the ugly casts from the user or use the likes of std::any as in the other nice answer.
That said, here's an alternative way to approach it (simplified but it should give you the right idea) which avoids map lookups except once on calling the get function for a new type, T:
#include <iostream>
#include <unordered_map>
#include <typeinfo>
#include <any>
class Foo
{
public:
template <class T>
T& get()
{
// Fetch a unique index for T to use for our std::vector.
const std::size_t n = type_index<T>();
// Resize if it's a new type we're encountering.
if (n >= bars.size())
bars.resize(n+1);
// Emplace if it's a former type of bar that's new for this instance
// of Foo.
if (!bars[n].has_value())
bars[n].emplace<T>();
// Returns the bar for that index cast to T&.
return std::any_cast<T&>(bars[n]);
}
private:
// Stores all the elements.
std::vector<std::any> bars;
// Returns a unique type index for T.
template <class T>
static std::size_t type_index()
{
// Using static here avoids repeat lookups into the hash map.
static const std::size_t n = lookup_type_index<T>();
return n;
}
// Looks up a unique type index for T.
template <class T>
static std::size_t lookup_type_index()
{
// Warning: hash_code is not guaranteed to be unique for all
// types in all compilers (two different types could return
// the same hash code, e.g.). I recommend using something else but
// that gets a bit involved (can expand and show you how if
// needed). Also consider a lock here for thread safety.
std::size_t key = typeid(T).hash_code();
auto it = idxs.find(key);
if (it != idxs.end())
return it->second;
idxs[key] = counter;
return counter++;
}
static inline std::unordered_map<std::size_t, std::size_t> idxs;
static inline std::size_t counter = 0;
};
int main()
{
using namespace std;
Foo f, f2;
f.get<int>() = 123;
f.get<double>() = 1.23;
f2.get<int>() = 456;
f2.get<double>() = 4.56;
cout << f.get<int>() << endl; // --> 123
cout << f.get<double>() << endl; // --> 1.23
cout << f2.get<int>() << endl; // --> 456
cout << f2.get<double>() << endl; // --> 4.56
}
I didn't bother to test it but it should give you the gist of the idea. Update: I bothered to test it and updated it with a hasty program you can run after discovering some typos just double-checking what I wrote and realizing I ought to at least try to compile what I write. To avoid constantly looking into a type map, we map types to an index into a vector. You can extend that with sub-indices and so forth as your original example suggests. The above illustrates the main idea.
Please note the warning in the code above about std::type_info::hash_code as it applies to both mine and the other answer. I can offer a safe and portable alternative and one that doesn't even require RTTI but that gets a bit involved. You can usually find a bunch of examples out there if you search for ways to portably map a type T to an integer at compile-time that you can use at runtime.

c++ pass on parameter by reference to another function in a function

I am fairly new to c/c++ and I am trying to build a program for a genetic algorithm (using MS Visual Studio 2013). I will spare you the details of this program, but I do have a problem with 'passing parameters by reference'.
Can I pass on a parameter by reference to another function, inside a function? Hereunder you can find a simple example of my code.
struct solution{
int list1[100];
int list2[100];
int list3[100];
int list4[100];
};
void function1(solution& foo)
{
// Algorithm that fills list2
function2(foo); // Fills in list3
function3(foo); // Fills in list4
}
void function2(solution& foo)
{
// algorithm to fill in list3
}
void function3(solution& foo)
{
// algorithm to fill in list4
}
void localSearch(solution& foo)
{
for(int i = 0; i < 10; i++)
{
// Change a random value in list1 of foo
// Rerun function1 and see if it is a better solution
function1(foo);
}
}
int main()
{
solution bar;
// Fill list1 of bar randomly by other function
function1(bar);
// Output finished solution
return 0;
}
If I try to do this, I get all sorts of errors... Next to that, my solution struct gets corrupted and the first position in list1 randomly changes back to 0.
I tried several things to mitigate this, but nothing seems to work. If I just pass on the solution to function1 by value, the programs seems to run, but more slowly, because it has to copy this large struct.
So my questions are:
1) Is it possible to pass (by reference) on a parameter that was passed by reference to another function, in function1?
2) What would be a better solution?
1) Is it possible to pass (by reference) on a parameter that was passed by reference to another function, in function1?
Yes, it is possible to pass the same variable, by reference to another function.
void f1(My_Class& m); // Forward declaration.
void f2(My_Class& m);
void f1(My_Class& m) // Definition.
{
f2(m);
}
void f2(My_Class& m)
{
;
}
The forward declaration gives the compiler a "heads up" on how functions are to be used (their syntax). Without forward declarations, the compiler would get the knowledge from their definitions. However, the definitions or forward declarations must come before the function call.
2) What would be a better solution?
Here are some ideas to improve your solution:
1) Use std::vector instead of arrays.
2) Consider a std::vector of structures, rather than an a structure of arrays:
struct List_Record
{
int item1;
int item2;
int item3;
int item4;
};
std::vector<List_Record> My_Lists(100);
// or
List_Record My_Array[100];
Having the items in a structure or record allows better data cache management by the processor (all items in a row are placed contiguously).
3) Create a method in the structure for initialization.
You should have a constructor that loads the data items with a default value.
Consider adding a method that loads the data items from a file (very useful for testing).

State data in functor members vs global function

When comparing functions and functors, it is often mentioned that one advantage of a functor over a function is that a functor is statefull.
However, in this code, it seems to me that a function may be statefull too. So what I am doing/understanding wrong?
struct Accumulator
{
int counter = 0;
int operator()(int i)
{
counter += i;
return counter;
}
};
int Accumulate(int i)
{
static int counter = 0;
counter += i;
return counter;
};
int main()
{
Accumulator acc;
std::vector<int> vec{1,2,3,4};
Accumulator acc2 = std::for_each(vec.begin(), vec.end(), acc);
int d1 = acc(0); // 0, acc is passed by value
int d2 = acc2(0); // 10
std::for_each(vec.begin(), vec.end(), Accumulate);
int d4 = Accumulate(0); // 10
return 0;
}
Each instance of a functor has its own state, while the static member of a function would be shared.
If you called for_each multiple times with the Accumulate() method, the counter would never reset, and each subsequent call would begin where the previous call ended. The functor would only have this behavior if each instance was reused. Creating a new functor would solve the problem.
You've used a static local variable to store state, but there's only one copy of the state no matter how many times you use Accumulate. And as chris points out, the initialization is only ever performed once.
With the functor, each new functor instance you create has its own independent state, initialized during instance creation.
Even if you provided a reset mechanism for the function version's state (for example, by moving the variable to a helper namespace where a second function can modify it), you still have only one accumulator at a time.
With functors, you have no problem developing a rule such as "prime numbers get accumulated here, even composites there, and odd composites into a third one" that uses three accumulators at once.

Can a function return more than 1 variable/structure/vector?

I am writing a function in which I am passing 3 vectors of different (struct)datatypes 1 vector will contains some values and after performing all the operations I am filling other two vectors with different sets of data. So my question is Is it possible that function returns more than 1 variable/struct/vectors.
eg..
func_name(vect1,&vect2,&vect3) //function definition
{
// steps of performing some operations
// enter code here vect1 contains data, vect2 & vect3 are empty
// after performing operation vect2 & vect3 filled with different set of data
is it possible to return vect2 & vect3 simultaneously.
}
func_name(vect1,vect2,vect3) // function calling.
Use references
template<typename T>
void func_name(std::vector<T>& vect1,
std::vector<T>& vect2,
std::vector<T>& vect3) //..Notice & sign
{
/* Your Processing */
}
func_name(vect1,vect2,vect3);
//Now all vect1, vect2 and vect3 will be updated as per func_name processing
Can use const std::vector<T>& vect1 as first argument if you don't have to update vect1
Interestingly, this is a deficiency of most high level languages, there is no restriction like this on the assembler level. I believe the main reason for it is the way we use the return values of functions in expressions.
In my eyes, there are two usable solutions: returning structs/tuples, or passing pointers to return parameters.
typedef struct {
int a, b, c;
} MyReturnType;
MyReturnType structFunc(...) {
return (MyReturnType){
.a = ...,
.b = ...,
.c = ...
};
}
//somewhere else
structFunc(...).c
Or, using pointers:
void pointerFunc(int* outA, int* outB, int* outC) {
*outA = ...;
*outB = ...;
*outC = ...;
}
//somewhere else
int a, b, c;
pointerFunc(&a, &b, &c);
I generally prefer the pointer approach because the function declaration stands on its own. However, the structure approach has it's value as well as it reduces the clutter on the calling side if only one return value is actually used.

choose correct template specialization at run-time

I have
template <int i> struct a { static void f (); };
with specializations done at different places in the code. How can I call the correct a<i>::f for an i known only at runtime?
void f (int i) { a<i>::f (); } // won't compile
I don't want to list all possible values of i in a big switch.
Edit:
I thought of something like
#include <iostream>
template <int i> struct a { static void f (); };
struct regf {
typedef void (*F)();
enum { arrsize = 10 };
static F v[arrsize];
template < int i > static int apply (F f) {
static_assert (i < arrsize, "");
v[i] = a<i>::f;
return 0;
}
};
regf::F regf::v[arrsize];
template <int i> struct reg { static int dummy; };
template <int i> int reg<i>::dummy = regf::apply<i> ();
void f (int i) { return regf::v[i] (); }
#define add(i) \
template <> struct a<i> : reg<i> { \
static void f () { std::cout << i << "\n"; } \
};
add(1)
add(3)
add(5)
add(7)
int main () {
f (3);
f (5);
}
but it crashes (did I miss something to force an instantiation?), and I don't like that dummy is not static const (and uses memory) and of course that arrsize is bigger than necessary.
Actual problem: To have a function generate (int i) that calls a<i>::generate () to generate an instance of class a<i> for an i given only at run-time. The design (classes a<i>) is given, they inherit from a base class and more specializations of a could be added at any time anywhere in the code, but I don't want to force everyone to change my generate (i) manually as that could be forgotten easily.
I am not sure that this is the best solution that you can get, as there might be better designs, at any rate you can use some metaprogramming to trigger the instantiation and registry of the functions:
// in a single cpp file
namespace {
template <unsigned int N>
int register_a() { // return artificially added
register_a<N-1>(); // Initialize array from 0 to N-1
regf::v[N] = &a<N>::f; // and then N
return N;
}
template <>
int register_a<0>() {
regf::v[0] = &a<0>::f; // recursion stop condition
return 0;
}
const int ignored = register_a<regf::arrsize>(); // call it
}
That code will instantiate the functions and register pointers to the static member functions. The fake return type is required to be able to force execution of the function in an static context (by means of using that function to initialize a static value).
This is quite prone to the static initialization fiasco. While regf::v is ok, any code that depends on regf::v containing the appropriate pointers during static initialization is bound to fail. You can improve this with the usual techniques...
From the bits and pieces that you have actually posted, my guess is that you are trying to use an abstract factory with automated registration from each one of the concrete factories. There are better ways of approaching the problem, but I think that this answer solves your question (I am unsure on whether this does solve your problem).
You have to. Templates are resolved and instantiated at compile-time. Apart from that, a switch needn't be inefficient. It usually compiles to a lookup table with very little overhead.
You can, however, use recursive template magic to have nested if/else blocks to replace the switch generated for you by the compiler. But a plain switch should be much more readable. Unless of course you have literally thousands of cases.
In either case, you need to know the set of values that i can have at compilation time since the compiler needs to know which templates to instantiate.
You can't pick a template specialization at runtime, they're by definition chosen at compile time.
The usual ways to solve the dispatch problem you're looking at are switch (as you surmised) or a vector or map of int to function pointer.
No, compiler needs to the instantiation of the template at compile time, for that it needs to know the value of i at compile time.
You can't as template instantiation is done at compile time.