How can I use template class as parameters of function? - c++

I want threading with template class parameter, but I don't know how I can use template class as parameter of thread method.
I already tried making method in template class, but I don't want it. People generally do not use this solution.
//....
//Linked List code
//.....
void func1(slist<T> s){
for (int i = 0; i < 1000; i++) {
s.push_(i);
}
} // this part is problem of my code.
int main() {
int i;
slist<int> s;
thread t1(func1,s); //Compile error.
func1(s); // here, too.
return 0;
}
i expect the result that threads compete with Linked list.

The generic solution:
template<typename T>
void func1(slist<T>& s){
for (int i = 0; i < 1000; i++) {
s.push_(i);
}
}
Or you can specialise for one specific type:
void func1(slist<int>& s){
for (int i = 0; i < 1000; i++) {
s.push_(i);
}
}
(Also be aware that you probably want to pass a reference to the list, rather than a copy)

As you want to make the thread accept a template, the function should be templated too.
template <typename T>
void func1(slist<T> s){ // most likely you need to pass by reference
for (int i = 0; i < 1000; i++) {
s.push_(i);
}
}
While calling the function in main,
int main() {
int i;
slist<int> s;
thread t1(func1<int>,s); //t1 needs to know which type it needs to instantiate of func1
t1.join(); // let the thread finish
return 0;
}

Related

Difficulty in passing function pointer of a class member function

In trying to implement a suggested answer here in my own context, I am running into a compilation error.
Consider code:
#include <iostream>
class SIMPLE {
public:
SIMPLE() { for (int i = 0; i < 5; i++) val[i] = 5; };
int retval(int index) { return val[index]; }
private:
int val[5];
};
void print_array_of_length5(int (*fnptr)(int index)){
for (int i = 0; i < 5; i++)
printf("%d ", fnptr(i));
}
int global_array[5] = { 0, 1, 2, 3, 4 };
int global_function(int index){
return global_array[index];
}
int main(){
print_array_of_length5(&global_function);//Works fine.
int (SIMPLE::*p)(int) = &SIMPLE::retval;//Following method suggested in the answer above
class SIMPLE smpl;
print_array_of_length5(smpl.*p);//Compile error: a pointer to a bound function may only be used to call the function
}
The function works when supplied with the address of a global function. It does not work when passed smpl.*p analogous to the method suggested. How should one fix this error?
You need another overload for print_array_of_length5 in order to pass a member function pointer:
template<typename T>
void print_array_of_length5(int (T::*fnptr)(int index), T& obj)
{
for(int i = 0; i < 5; ++i)
{
printf("%d ", (obj.*fnptr)(i));
}
}
int main()
{
SIMPLE smpl;
print_array_of_length5(&SIMPLE::retval, smpl);
}
You can't pass a non-static member function pointer as a regular function pointer. Member functions have access to the this pointer, and the way they get that is via an invisible implicit function parameter. You need to have the object on which to call the function, and the function itself, be bound together, which a function pointer simply can't do.
What we can do is make print_array_of_length5 a function template, and allow it to take any type of callable. That would give you something like this:
template <typename Function>
void print_array_of_length5(Function func){
for (int i = 0; i < 5; i++)
printf("%d ", func(i));
}
To call it with a non-static member function, you can use a lambda expression, or std::bind(), like this:
SIMPLE smpl;
print_array_of_length5([&smpl](int foo){ return smpl.retval(foo); });
using namespace std::placeholders;
SIMPLE smpl;
auto func = std::bind(&SIMPLE::retval, &smpl, _1);
print_array_of_length5(func);

Invoke a function in context of a class instance or method for performance analysis

Performance analysis question: Is there a way to execute a function in context of a class, or a method of a class?
I would like to analyze the performance of a specific segment of logic. What I envision is something like this
(Disclaimer: rough example just to illustrate a point. Will not compile).
const int DEBUG_LEVEL = 7;
class PerfWrapper {
public:
PerfWrapper(int f) {} // Constructor: take function as argument
void invoke() {} // Invoke the function passed as argument
double execution_time() {
begin = std::chrono::high_resolution_clock::now();
// etc..
}
double memory_usage() {}
private:
}
int foo() {
int sum{0}
for (int i=0; i<1000; ++i)
for (int j=0; j<MAX; ++j)
sum += i * j;
return sum;
}
int main() {
if (DEBUG_LEVEL = 7)
PerfWrapper p(foo); // Create an instance, passing foo as an argument
// below foo() is called in context of the performance wrapper
int myTime = p.invoke().execution_time(); // Invokes foo in context of p and tracks execution time
int myMemory = p.invoke().memory_usage(); // Same, except gathering memory usage info.
// etc..
}
}
Here we have class PerfWrapper. When instantiated, resulting methods on the object have the ability to accept a function as an argument, and execute a function in context of the class. It will take perf measurements, results of which are accessible through the interface.
Note the "DEBUG_LEVEL" setting. If performance profiling is needed then simply set the DEBUG_LEVEL to 7.
Have you seen anything like this? If not, how is the analysis best accomplished? I know that it seems a bit out there, but hopefully not so much. Thx, Keith :^)
Maybe you are looking for function pointers, which could be used as shown in the following simplified code:
typedef int(*aFooFunctionType)(void);
class PerformanceTest {
public:
PerformanceTest(aFooFunctionType fooFuncPtr) { m_fooFuncPtr = fooFuncPtr; }
void test() {
int x = m_fooFuncPtr();
// do something with x (or not...)
};
private:
aFooFunctionType m_fooFuncPtr;
};
int fooFunc(void) {
return 100;
}
int main(int argc, char* argv[]) {
PerformanceTest pTest(fooFunc);
pTest.test();
return 0;
}
You can wrap almost anything in a std::function. I would suggest use of a std::function in PerfWrapper to get the execution time. I don't have anything for measuring memory usage, though.
Example code:
#include <iostream>
#include <functional>
#include <chrono>
class PerfWrapper
{
public:
PerfWrapper(std::function<void()> f) : f_(f), execution_time_{} {}
void invoke()
{
auto begin = std::chrono::high_resolution_clock::now();
f_();
auto end = std::chrono::high_resolution_clock::now();
execution_time_ = end-begin;
}
double execution_time()
{
return execution_time_.count();
}
std::function<void()> f_;
std::chrono::duration<double> execution_time_;
};
unsigned long foo()
{
unsigned long sum{0};
for (int i=0; i<10000; ++i)
for (int j=0; j<2000; ++j)
sum += i * j;
return sum;
}
int main()
{
PerfWrapper pr([](){std::cout << foo() << std::endl;});
pr.invoke();
std::cout << "Execution time: " << pr.execution_time() << std::endl;
}
Output on my setup:
99940005000000
Execution time: 0.0454077
Consider using a template free function, with a reference parameter to extract the performance data. This example will:
Accept function pointers and functors (including std::function, which means it can work with methods, too).
Return the same value the proxied function call returns, so you can use both the measurement data and the call result.
struct measurement {
double execution_time;
double memory_usage;
};
template <typename FN, typename... T>
inline auto measure(FN fn, measurement& m, T&&... args) -> decltype(fn(std::forward<T>(args)...))
{
auto&& result = fn(std::forward<T>(args)...);
m.execution_time = 0; // example
m.memory_usage = 0;
return result;
}

Organising C++ code

I am looking for some advice on how to organise my C++ code.
I have an int array, side, that I would like to be static in the sense that its value is kept constant between calls. This is because my function foo(), will modify the array side recursively and so I don't want copies to be made of side. Furthermore, the size of side can only be determined at compile time from the size of a vector that is passed into the function bar().
I have thought of the following structure to layout such a problem.
I keep a global int pointer, side, which I can then use to point to the address of my int array and then use the pointer *side within foo to do my modifications.
Please can you give me advise on the layout and organisation of this code? I am quite new to C++ so would appreciate any advice on the below structure.
#include <iostream>
#include <vector>
using namespace std;
int *side;
class A {
public:
int foo(bool);
int bar(vector<int>);
void set_n(int n){ class_n = n;};
private:
int class_n;
};
int A::foo(bool fl)
{
int n = class_n;
for(int i = 0; i < n; i++) {
// modify side[] and then recursively call foo
}
return 0;
}
int A::bar(vector<int> t)
{
int size = t.size();
set_n(size);
int a = foo(true);
int *side_local = new int[size];
for(int i = 0; i < size; i++) {
side_local[i] = 0;
}
side = side_local;
return 0;
}
int main()
{
A a;
vector<int> t = {1, 2, 3};
a.bar(t);
return 0;
}
A recursive call can pass a pointer to itself:
void foo(int *pList)
{
foo(pList); // recursive
}
the same list is then being worked on.
That being said, since foo is inside a class you wouldn't need a global either, but a member variable.
class A
{
int *pMemberList;
...
void foo();
}
now foo can see pMemberList all the time.
BUT ... passing it is probably a better option as in the future your class might house 2 lists that you want to do foo on.

Code duplication prevention : 2 long functions differing only in inner loop

I have two functions, f_a and f_b following a general form,
void f_x(){
for (int i = 0; i < 10; ++ i){
for (int j = 0; j < 10; ++ j){
//do loads of generic stuff
//do stuff specific to x
}
}
};
I don't want to either (1) write the for loops more than once or (2) have a condition to check in the inner loop to determine whether to perform a- or b- specifics. One solution is to use templates as follows,
template <int I>
inline void specific(){}
template <>
inline void specific<0> { // do a-specific tasks }
template <>
inline void specific<1> { // do b-specific tasks }
template <int I>
void f(){
for (int i = 0; i < 10; ++ i){
for (int j = 0; j < 10; ++j){
//do loads of generic stuff
specific<I>();
}
}
}
inline void f_a(){
f<0>();
}
inline void f_b(){
f<1>();
}
My questions are :
Does this seem like a fair solution?
Out of interest, is there a solution which does not use templates?
Instead of having the specific functions being templates, just let them be normal functions and pass then in to the your generic f function.
Something like
template<typename F>
void f(F func){
for (int i = 0; i < 10; ++ i){
for (int j = 0; j < 10; ++j){
// Generic stuff...
// Call the specific function
func();
}
}
}
void specific_x() { ... }
void specific_y() { ... }
void f_x(){
f(specific_x);
}
void f_y(){
f(specific_y);
}
Similar to your solution, but more generic as you now can pass in any callable object to your function f, including function pointers (which is used in the example above), functors, lambdas and everything else that can be called.

How to pass a VLA to a function template?

I have the following code which could not be complied.
using namespace std;
void f(int);
template<typename T1, size_t N>
void array_ini_1d(T1 (&x)[N])
{
for (int i = 0; i < N; i++)
{
x[i] = 0;
}
}
What is the proper way to pass the array if the main is something like below.
int main()
{
int a;
cin >> a;
int n = a / 4;
f(n);
return 0;
}
void f(int n)
{
int arr[n];
array_ini_1d(arr);
}
error: no matching function to call to array_ini_1d..............
The problem is that variable size arrays are not supported by c++, and is only supported as compilers extension. That means, the standard doesn't say what should happen, and you should see if you can find in compiler's documentation, but I doubt that such corner cases are documented.
So, this is the problem :
int arr[n];
The solution is to avoid it, and use something supported by c++, like for example std::vector.
I don't think the compiler can deduce the size of a variable-length array in a template. Also, don't forget to forward declare f before you use it. Variable-length arrays are a GCC extension and you should get a warning regarding their use.
You may declare your function like this:
template <typename A, size_t N> void f(A a[N]) {
for(size_t i = 0; i < N; i++)
cout << a[i];
}
However, the problem is that when you call the function, the compiler won't deduce the template parameters, and you will have to specify them explicitly.
char arr[5] = {'H', 'e', 'l', 'l', 'o'};
int main()
{
//f(arr); //Won't work
f<char, sizeof(arr)/sizeof(arr[0])>(arr);
cout << endl;
return 0;
}
Unfortunately, that ruins the very idea...
UPD: And even that code does NOT work for an array that has variable length, for the length is calculated at runtime, and the template parameters are defined at compilation time.
UPD2: If using std::vector you may create it initialized:
vector<int> arr(n, 0);
Or you may fill it with fill from <algorithm> when needed:
std::fill(arr.begin(), arr.end(), 0);
As you use Variable length array (VLA) (compiler extension), compiler cannot deduce N.
You have to pass it by pointer and give the size:
template<typename T>
void array_ini_1d(T* a, std::size_t n)
{
for (std::size_t i = 0; i != n; ++i) {
a[i] = 0;
}
}
void f(int n)
{
int arr[n];
array_ini_1d(arr);
}
Or use std::vector. (no extension used so). Which seems cleaner:
template<typename T>
void array_ini_1d(std::vector<T>& v)
{
for (std::size_t i = 0, size = v.size(); i != n; ++i) {
a[i] = 0; // or other stuff.
}
}
void f(int n)
{
std::vector<int> arr(n); // or arr(n, 0).
array_ini_1d(arr);
}
Template parameters must be resolved at compile-time.
There is no way that a function template with parameter size_t N can match any sort of array or other container whose size comes from a run-time input.
You will need to provide another version of the array_1d_ini which does not have the size as a template parameter.
template<typename T, size_t N>
void f(T* a)
{
/* add your code here */
}
int main()
{
int a[10];
f<int, 10>(a);
return 0;
}