C++ how call template's class constructor - c++

I have such piece of code:
template <class T>
struct Rgb
{
T *r, *g, *b;
Rgb(int nr, int ng, int nb)
{
r = new T(nr);
g = new T(ng);
b = new T(nb);
}
Rgb(int n)
{
Rgb(n, n, n);
}
~Rgb()
{
delete r;
delete g;
delete b;
}
};
I have done it in such way, because I want to be able to create objects like:
Rgb<std::vector<int>> a(10); // so it creates 3 vectors inside,
// each with 10 elements or
Rgb<std::deque<double>> a(2, 5, 4); // so it creates 3 deques inside
// with different sizes
But the implementation I have given above does not work. Help me please... thanks...

If you compiler supports constructor delegation (which e.g. Clang 3.2 does) you can do the following:
Rgb(int n) : Rgb(n, n, n)
{
}
What you're doing is constructing a temporary Rgb instance in the constructor, which will fail once the uninitialized r, g and b get deleted.
Otherwise I'd recommend either creating a common init function that does the initialization or simply duplicate the code. And as the comments are noting you shouldn't use new here (that's almost always a code smell in modern C++ code). Bringing this together:
template <class T>
struct Rgb
{
T r, g, b;
Rgb(int nr, int ng, int nb) : r(nr), g(ng), b(nb)
{ }
Rgb(int n) : r(n), g(n), b(n)
{ }
~Rgb()
{ }
};

Related

How to create a true array from a vector

I have a vector (of strings) that I need to pass into a function that only accepts a true array(not a pointer).
//Function only accepts arrays, not vectors or pointers
//It has to be an array so that the compiler can figure out N
template<typename T, typename U, size_t N>
T* createElementFromArray(U (&a)[N]){
return createElementFromArrayHelper<T>(std::make_index_sequence<N>{}, a);
}
The problem is, I need to dynamically allocate the array so that it is the same size as the vector, but new[] only returns a pointer not a true array.
How do I dynamically allocate a true array, not a pointer? Or is there another way to create a vector from an array(the array needs to be the exact same size as the vector)?
Based on the code in this answer, where you got CreateElementFromArray() from, what you are asking for is simply not possible at all.
CreateElementFromArray() converts a fixed-sized array of N values into a sequence of N parameters passed to T's constructor at compile-time. For example, this code from that same answer:
struct A {
A(int a, int b) : x(a), y(b) {}
int x, y;
};
int Aargs[] = { 1, 2 };
A* a = createElementFromArray<A>(Aargs);
delete a;
Is translated by the compiler into this code:
struct A {
A(int a, int b) : x(a), y(b) {}
int x, y;
};
int Aargs[] = { 1, 2 };
A* a = new A(Aargs[0], Aargs[1]);
delete a;
That kind of translation is simply not possible with a std::vector or other dynamic array allocated at runtime.
However, if T's constructor accepts a vector/array as input, you can use createElement() from that same answer instead:
template<typename T, typename... TArgs>
T* createElement(TArgs&&... MArgs)
Whatever you pass to createElement() gets passed as-is to T' s constructor. For example:
struct A {
A(int* values, size_t N) : values(values, values+N) {}
A(const vector<int> &values) : values(values) {}
vector<int> values;
};
vector<int> Aargs1 = { 1, 2 };
array<int, 3> Aargs2 = { 1, 2, 3 };
int* Aargs3 = new int[4]{ 1, 2, 3, 4 };
A* a = createElement<A>(Aargs1);
delete a;
a = createElement<A>(Aargs1.data(), Aargs1.size());
delete a;
a = createElement<A>(Aargs2.data(), Aargs2.size());
delete a;
a = createElement<A>(Aargs3, 4);
delete a;
delete[] Aargs3;

C++ avoid writing two similar functions

I want to have two version a function by hiding or not hiding several lines of code at the middle and also near the end of the function with template or other means. How to do that?
The functions are performance critical. They got run a gazillion of gazillion times.
You could implement the first one with a default parameter:
int A(int a, int b, int c, int d = 0)
{
// stuff
}
You can factor out the common part and use a function object to pass the differing part:
template<class Fun>
int AB(Fun&& fun){
int x = 0;
Outer Loop{
Inner Loop{
x = std::forward<Fun>(fun)();
}
}
return x;
}
int a, b, c, d;
// ... initialize
int result1 = AB([a,b,c]{
return a + b;
});
int result2 = AB([a,b,c,d]{
return a + b + c*d;
});
You could make this even more general by templating the return type.
There are no branches and an optimizing compiler will be able to expand the function call inline. The latter is the reason to prefer function objects to function pointers.
Honestly, I would suggest you to re-implement your code. But the one thing that is coming to my mind is using function as parameter, see below (you may also use lambda expression):
int fun1(int a, int b, int c, int d) {
return a + b;
}
int fun2(int a, int b, int c, int d) {
return a + b + c*d;
}
template <int (*FUN)(int, int, int, int)> int fun_main(int a, int b, int c, int d = 0) {
int x = 0;
Outer Loop{
Inner Loop{
x += FUN(a, b, c, d);
}
}
return x;
}
Then somwhere in your code:
fun_main<fun1>(1, 2, 3, 4);

In-Place Ordering of Elements

Does Phobos have some variadic algorithm to order l-value reference arguments in place? Something like
int a=3;
int b=2;
int c=1;
orderInPlace(a,b,c);
// a is now 1
// b is now 2
// c is now 3
Also a functional variant, say order(a, b, c), that returns a tuple would also be nice.
If not, I guess we should make use of std.algorithm:swap.
See also http://forum.dlang.org/thread/eweortsmcmibppmvtriw#forum.dlang.org#post-eweortsmcmibppmvtriw:40forum.dlang.org.
Adam's solution works, although it uses a temporary copy of the elements. With a small modification to std.algorithm, it's possible to write a version which sorts the elements in-place:
import std.algorithm;
import std.stdio;
import std.traits;
import std.typecons;
struct SortableRef(T)
{
private T * _p;
#property ref T value() { return *_p; }
alias value this;
void opAssign(T * value) { _p = value; }
#disable void opAssign(SortableRef!T value);
void proxySwap(SortableRef!T other) { swap(*_p, *other._p); }
}
template PointerTo(T) { alias T* PointerTo; }
void orderInPlace(T...)(ref T values)
if (!is(CommonType!(staticMap!(PointerTo, T)) == void))
{
alias CommonType!T E;
SortableRef!E[values.length] references;
foreach (i, ref v; values)
references[i] = &v;
references[].sort();
}
void main()
{
int a=3;
int b=1;
int c=2;
orderInPlace(a, b, c);
writeln([a, b, c]);
}
However, it is only practical if the values passed to orderInPlace are large, unassignable, or otherwise impractical to copy.
I don't think Phobos has one, but you could make your own kinda like this:
void orderInPlace(T...)(ref T t) {
import std.algorithm;
T[0][T.length] buffer;
foreach(idx, a; t)
buffer[idx] = a;
auto sorted = sort(buffer[]);
foreach(idx, a; t)
t[idx] = sorted[idx];
}
std.algorithm,sort needs an array, but that's easy enough - we copied the tuple into a stack array, sorted it, then copied the info back into the tuple. So maybe not perfect but it'd work. You can make it functional by just returning t instead of doing it ref.
A sorting network here is probably what would be most efficient given the low number of arguments, and the fact that their number is compile-time known (no loop conditions).
bubble sort lends itself well to being sort network'ed. I threw this together. It works and is really simple:
import std.stdio, std.string;
void bubbleSort(T...)(ref T values)
{
static if (T.length > 1)
{
foreach(I, _; T[0 .. $ - 1])
{
pragma(msg, format("[%s %s]", I, I + 1));
compareAndSwap(values[I], values[I + 1]);
}
bubbleSort(values[0 .. $ - 1]);
}
}
void compareAndSwap(T)(ref T a, ref T b)
{
import std.algorithm;
if(a > b)
swap(a, b);
}
void main()
{
int a = 10;
int b = 30;
int c = 11;
int d = 20;
int e = 4;
int f = 330;
int g = 21;
int h = 110;
shellSort(a, b, c, d, e, f, g, h);
writefln("%s %s %s %s %s %s %s %s!", a, b, c, d, e, f, g, h);
}
Although to be honest, if this was standard library, any sorting network of less than 10 arguments should be hand written.
EDIT: I completely changed the previous algorithm, which was actually highly ineficient. Bubble sort is not optimal, but it actually works OK for sorting algorithms. There's some pragmas in there to see the network that's built.

wrapping C callbacks with C++ lambdas, possible to use template polymorphism?

Okay, I have posted a few questions lately related to wrapping a C callback API with a C++11-ish interface. I have almost got a satisfying solution, but I think it could be more elegant and need the help of some template metaprogramming wizards :)
Bear with me, as the example code is a little long, but I've tried to demonstrate the problem in one shot. Basically, the idea is that, given a list of function pointers and data context pointers, I want to provide a callback mechanism that can be provided with,
Function pointers
Function objects (functors)
Lambdas
Moreover, I want to make these functions callable by a variety of prototypes. What I mean is, the C API provides about 7 different parameters to the callback, but in most cases the user code is really only interested in one or two of these. So I'd like the user to be able to specify only the arguments he is interested in. (This extends from the point of allowing lambdas in the first place... to allow conciseness.)
In this example, the nominal C callback takes an int and a float parameter, and an optional float* which can be used to return some extra data. So the intention of the C++ code is to be able to provide a callback of any of these prototypes, in any form that is "callable". (e.g. functor, lambda, etc.)
int callback2args(int a, float b);
int callback3args(int a, float b, float *c);
Here is my solution so far.
#include <cstdio>
#include <vector>
#include <functional>
typedef int call2args(int,float);
typedef int call3args(int,float,float*);
typedef std::function<call2args> fcall2args;
typedef std::function<call3args> fcall3args;
typedef int callback(int,float,float*,void*);
typedef std::pair<callback*,void*> cb;
std::vector<cb> callbacks;
template <typename H>
static
int call(int a, float b, float *c, void *user);
template <>
int call<call2args>(int a, float b, float *c, void *user)
{
call2args *h = (call2args*)user;
return (*h)(a, b);
}
template <>
int call<call3args>(int a, float b, float *c, void *user)
{
call3args *h = (call3args*)user;
return (*h)(a, b, c);
}
template <>
int call<fcall2args>(int a, float b, float *c, void *user)
{
fcall2args *h = (fcall2args*)user;
return (*h)(a, b);
}
template <>
int call<fcall3args>(int a, float b, float *c, void *user)
{
fcall3args *h = (fcall3args*)user;
return (*h)(a, b, c);
}
template<typename H>
void add_callback(const H &h)
{
H *j = new H(h);
callbacks.push_back(cb(call<H>, (void*)j));
}
template<>
void add_callback<call2args>(const call2args &h)
{
callbacks.push_back(cb(call<call2args>, (void*)h));
}
template<>
void add_callback<call3args>(const call3args &h)
{
callbacks.push_back(cb(call<call3args>, (void*)h));
}
template<>
void add_callback<fcall2args>(const fcall2args &h)
{
fcall2args *j = new fcall2args(h);
callbacks.push_back(cb(call<fcall2args>, (void*)j));
}
template<>
void add_callback<fcall3args>(const fcall3args &h)
{
fcall3args *j = new fcall3args(h);
callbacks.push_back(cb(call<fcall3args>, (void*)j));
}
// Regular C-style callback functions (context-free)
int test1(int a, float b)
{
printf("test1 -- a: %d, b: %f", a, b);
return a*b;
}
int test2(int a, float b, float *c)
{
printf("test2 -- a: %d, b: %f", a, b);
*c = a*b;
return a*b;
}
void init()
{
// A functor class
class test3
{
public:
test3(int j) : _j(j) {};
int operator () (int a, float b)
{
printf("test3 -- a: %d, b: %f", a, b);
return a*b*_j;
}
private:
int _j;
};
// Regular function pointer of 2 parameters
add_callback(test1);
// Regular function pointer of 3 parameters
add_callback(test2);
// Some lambda context!
int j = 5;
// Wrap a 2-parameter functor in std::function
add_callback(fcall2args(test3(j)));
// Wrap a 2-parameter lambda in std::function
add_callback(fcall2args([j](int a, float b)
{
printf("test4 -- a: %d, b: %f", a, b);
return a*b*j;
}));
// Wrap a 3-parameter lambda in std::function
add_callback(fcall3args([j](int a, float b, float *c)
{
printf("test5 -- a: %d, b: %f", a, b);
*c = a*b*j;
return a*b*j;
}));
}
int main()
{
init();
auto c = callbacks.begin();
while (c!=callbacks.end()) {
float d=0;
int r = c->first(2,3,&d,c->second);
printf(" result: %d (%f)\n", r, d);
c ++;
}
}
Okay, as you can see, this actually works. However, I find the solution of having to explicitly wrap the functors/lambdas as std::function types kind of inelegant. I really wanted to make the compiler match the function type automatically but this doesn't seem to work. If I remove the 3-parameter variant, then the fcall2args wrapper is not needed, however the presence of the fcall3args version of add_callback makes it apparently ambiguous to the compiler. In other words it seems to not be able to do pattern matching based on the lambda call signature.
A second problem is that I'm of course making copies of the functor/lambda objects using new, but not deleteing this memory. I'm not at the moment sure what the best way will be to track these allocations, although I guess in a real implementation I could track them in an object of which add_callback is a member, and free them in the destructor.
Thirdly, I don't find it very elegant to have specific types call2args, call3args, etc., for each variation of the callback I want to allow. It means I'll need an explosion of types for every combination of parameters the user might need. I was hoping there could be some template solution to make this more generic, but I am having trouble coming up with it.
Edit for explanation: The definition in this code, std::vector<std::pair<callback*,void*>> callbacks, is part of the problem definition, not part of the answer. The problem I am trying to solve is to map C++ objects onto this interface--therefore, proposing better ways to organize this std::vector doesn't solve the problem for me. Thanks. Just to clarify.
Edit #2: Okay, forget the fact that my example code uses std::vector<std::pair<callback*,void*>> callbacks to hold the callbacks. Imagine instead, as this is the actual scenario, that I have some C library implementing the following interface:
struct someobject *create_object();
free_object(struct someobject *obj);
add_object_callback(struct someobject *obj, callback *c, void *context);
where callback is,
typedef int callback(int a,float b,float *c, void *context);
Okay. So "someobject" will experience external events of some kind, network data, or input events, etc., and call its list of callbacks when these happen.
This is a pretty standard implementation of callbacks in C. Importantly, this is an existing library, something for which I cannot change, but I am trying to write a nice, idiomatic C++ wrapper around it. I want my C++ users to be able to add lambdas as callbacks. So, I want to design a C++ interface that allows users to be able to do the following:
add_object_callback(struct someobject *obj, func);
where func is one of the following:
a regular C function that doesn't use context.
a functor object
a lambda
Additionally, in each case, it should be possible for the function/functor/lambda to have either of the following signatures:
int cb2args(int a, float b);
int cb2args(int a, float b, float *c);
I think this should be possible, and I got about 80% of the way there, but I'm stuck on template polymorphism based on the call signature. I don't know offhand whether it's possible. Maybe it needs some voodoo involving function_traits or something, but it's a little beyond my experience. In any case, there are many, many C libraries that use such an interface, and I think it would be great to allow this kind of convenience when using them from C++.
Since you are using the C API in C++11, you could as well just wrap the whole thing in a C++ class. This is also necessary, as you mentioned in the 2nd problem, to solve the resource leak.
Also remember that a lambda expression without capture can be implicitly converted to a function pointer. This could remove all the call<*> because they can be moved into the add_callbacks.
And finally, we could use SFINAE to remove the fcall3args types. Here is the result.
class SomeObject {
// The real object being wrapped.
struct someobject* m_self;
// The vector of callbacks which requires destruction. This vector is only a
// memory store, and serves no purpose otherwise.
typedef std::function<int(int, float, float*)> Callback;
std::vector<std::unique_ptr<Callback>> m_functions;
// Add a callback to the object. Note the capture-less lambda.
template <typename H>
void add_callback_impl(H&& h) {
std::unique_ptr<Callback> callback (new Callback(std::forward<H>(h)));
add_object_callback(m_self, [](int a, float b, float* c, void* raw_ctx) {
return (*static_cast<Callback*>(raw_ctx))(a, b, c);
}, callback.get());
m_functions.push_back(std::move(callback));
}
public:
SomeObject() : m_self(create_object()) {}
~SomeObject() { free_object(m_self); }
// We create 4 public overloads to add_callback:
// This only accepts function objects having 2 arguments.
template <typename H>
auto add_callback(H&& h) -> decltype(h(1, 10.f), void()) {
using namespace std::placeholders;
add_callback_impl(std::bind(std::forward<H>(h), _1, _2));
}
// This only accepts function objects having 3 arguments.
template <typename H>
auto add_callback(H&& h) -> decltype(h(1, 1.0f, (float*)0), void()) {
add_callback_impl(std::forward<H>(h));
}
// This only accepts function pointers.
void add_callback(int(*h)(int, float)) const {
add_object_callback(m_self, [](int a, float b, float* c, void* d) {
return reinterpret_cast<int(*)(int, float)>(d)(a, b);
}, reinterpret_cast<void*>(h));
}
// This only accepts function pointers.
void add_callback(int(*h)(int, float, float*)) const {
add_object_callback(m_self, [](int a, float b, float* c, void* d) {
return reinterpret_cast<int(*)(int, float, float*)>(d)(a, b, c);
}, reinterpret_cast<void*>(h));
}
// Note that the last 2 overloads violates the C++ standard by assuming
// sizeof(void*) == sizeof(func pointer). This is valid in POSIX, though.
struct someobject* get_raw_object() const {
return m_self;
}
};
So the init() becomes:
void init(SomeObject& so) {
// A functor class
class test3 { ... };
so.add_callback(test1);
so.add_callback(test2);
// Some lambda context!
int j = 5;
so.add_callback(test3(j));
so.add_callback([j](int a, float b) -> int {
printf("test4 -- a: %d, b: %f", a, b);
return a*b*j;
});
so.add_callback([j](int a, float b, float *c) -> int {
printf("test5 -- a: %d, b: %f", a, b);
*c = a*b*j;
return a*b*j;
});
}
The full testing code (I'm not putting that to ideone here, because g++ 4.5 doesn't support implicitly converting a lambda to a function pointer, nor the range-based for.)
#include <vector>
#include <functional>
#include <cstdio>
#include <memory>
struct someobject;
struct someobject* create_object(void);
void free_object(struct someobject* obj);
void add_object_callback(struct someobject* obj,
int(*callback)(int, float, float*, void*),
void* context);
class SomeObject {
// The real object being wrapped.
struct someobject* m_self;
// The vector of callbacks which requires destruction. This vector is only a
// memory store, and serves no purpose otherwise.
typedef std::function<int(int, float, float*)> Callback;
std::vector<std::unique_ptr<Callback>> m_functions;
// Add a callback to the object. Note the capture-less lambda.
template <typename H>
void add_callback_impl(H&& h) {
std::unique_ptr<Callback> callback (new Callback(std::forward<H>(h)));
add_object_callback(m_self, [](int a, float b, float* c, void* raw_ctx) {
return (*static_cast<Callback*>(raw_ctx))(a, b, c);
}, callback.get());
m_functions.push_back(std::move(callback));
}
public:
SomeObject() : m_self(create_object()) {}
~SomeObject() { free_object(m_self); }
// We create 4 public overloads to add_callback:
// This only accepts function objects having 2 arguments.
template <typename H>
auto add_callback(H&& h) -> decltype(h(1, 10.f), void()) {
using namespace std::placeholders;
add_callback_impl(std::bind(std::forward<H>(h), _1, _2));
}
// This only accepts function objects having 3 arguments.
template <typename H>
auto add_callback(H&& h) -> decltype(h(1, 1.0f, (float*)0), void()) {
add_callback_impl(std::forward<H>(h));
}
// This only accepts function pointers.
void add_callback(int(*h)(int, float)) const {
add_object_callback(m_self, [](int a, float b, float* c, void* d) {
return reinterpret_cast<int(*)(int, float)>(d)(a, b);
}, reinterpret_cast<void*>(h));
}
// This only accepts function pointers.
void add_callback(int(*h)(int, float, float*)) const {
add_object_callback(m_self, [](int a, float b, float* c, void* d) {
return reinterpret_cast<int(*)(int, float, float*)>(d)(a, b, c);
}, reinterpret_cast<void*>(h));
}
// Note that the last 2 overloads violates the C++ standard by assuming
// sizeof(void*) == sizeof(func pointer). This is required in POSIX, though.
struct someobject* get_raw_object() const {
return m_self;
}
};
//------------------------------------------------------------------------------
int test1(int a, float b) {
printf("test1 -- a: %d, b: %f", a, b);
return a*b;
}
int test2(int a, float b, float *c) {
printf("test2 -- a: %d, b: %f", a, b);
*c = a*b;
return a*b;
}
void init(SomeObject& so) {
// A functor class
class test3
{
public:
test3(int j) : _j(j) {};
int operator () (int a, float b)
{
printf("test3 -- a: %d, b: %f", a, b);
return a*b*_j;
}
private:
int _j;
};
so.add_callback(test1);
so.add_callback(test2);
// Some lambda context!
int j = 5;
so.add_callback(test3(j));
so.add_callback([j](int a, float b) -> int {
printf("test4 -- a: %d, b: %f", a, b);
return a*b*j;
});
so.add_callback([j](int a, float b, float *c) -> int {
printf("test5 -- a: %d, b: %f", a, b);
*c = a*b*j;
return a*b*j;
});
}
//------------------------------------------------------------------------------
struct someobject {
std::vector<std::pair<int(*)(int,float,float*,void*),void*>> m_callbacks;
void call() const {
for (auto&& cb : m_callbacks) {
float d=0;
int r = cb.first(2, 3, &d, cb.second);
printf(" result: %d (%f)\n", r, d);
}
}
};
struct someobject* create_object(void) {
return new someobject;
}
void free_object(struct someobject* obj) {
delete obj;
}
void add_object_callback(struct someobject* obj,
int(*callback)(int, float, float*, void*),
void* context) {
obj->m_callbacks.emplace_back(callback, context);
}
//------------------------------------------------------------------------------
int main() {
SomeObject so;
init(so);
so.get_raw_object()->call();
}

Multi-dimensional array

I need to create a function that has a parameter which is a multi-dimensional array with two dimensions being user-specified, e.g.
int function(int a, int b, int array[a][b])
{
...
}
How would I do that in C++ ?
Are the dimensions known at compile-time? In that case, turn them into template parameters and pass the array by reference:
template<int a, int b>
int function(int(&array)[a][b])
{
...
}
Example client code:
int x[3][7];
function(x);
int y[6][2];
function(y);
Assuming the dimensions are not known at compile time, you emulate a two dimensional array with a one dimensional array:
int& getat(int x, int y, int r, int c, int *array) {return array[y*c+x];}
int function(int a, int b, int *array) {
getat(4, 2, a, b, array) = 32; //array[4,2] = 32
}
or, for safety, wrap it all in a class:
template <class T>
class array2d {
std::vector<T> data;
unsigned cols, rows;
public:
array2d() : data(), cols(0), rows(0) {}
array2d(unsigned c, unsigned r) : data(c*r), cols(c), rows(r) {}
T& operator()(unsigned c, unsigned r) {
assert(c<cols&&r<rows);
return data[r*cols+c];
}
};
or, best yet, use Boost's Multidimensional Array, which will be better than anything mere mortals could write.
I'm not sure if this work, because your question and code are not the same, according to your code the function can have 3 parameters, so this would work:
int function(int a, int b, int** &array)
{
array = new int*[a];
for (int i =0;i<a;i++)
array[i] = new int[b];
// I don't know why you are returning int, probably doing something here....
}
However your question says that your function can take only one parameter, so:
if the dimensions are known at compile time, then Fred's Answer is the best (it charmed me in fact! :) ).
if not, I can't see any possible solution that allows passing more than one user-specified value other than encapsulating all these values in one object.
Like this:
class Foo {
public:
Foo(int d1, int d2)
{ a = d1; b = d2; }
int a,b;
int** array;
};
int function(Foo &f)
{
f.array = new int*[f.a];
for (int i = 0;i<f.a;i++)
f.array[i] = new int[f.b];
// I don't know why you are returning int, probably doing something here....
}
Though I find it a bad idea, in fact the function could be a parameterless method instead:
class Foo {
public:
Foo(int d1, int d2)
{ a = d1; b = d2; }
void Create() // Or could do this right in the Constructor
{
array = new int*[a];
for (int i = 0;i<a;i++)
array[i] = new int[b];
}
private:
int a,b;
int** array;
};
Still this is a bad idea, because you are reinventing the wheel, as there are a perfect class in the STL to do all the work for you:
vector< vector<int> > v; // Now v is a 2D array