Passing Arguments as Ref type deduction - eigen3

i my settings looks like:
class Base
{
public:
virtual void eval(const Ref< const Matrix<float,Dynamic,1>> in, Ref<Matrix<float,Dynamic,1>> out) = 0;
virtual void eval( const Ref< const Matrix<float,Dynamic,Dynamic,RowMajor>> inp, Ref<Matrix<float,Dynamic,Dynamic,RowMajor>> out) = 0;
};
class Test : Base
{
public:
void eval(const Ref< const Matrix<float,Dynamic,1>> in, Ref<Matrix<float,Dynamic,1>> out) override
{
out = in;
};
void eval( const Ref< const Matrix<float,Dynamic,Dynamic,RowMajor>> in, Ref<Matrix<float,Dynamic,Dynamic,RowMajor>> out)override
{
for(std::size_t i=0;i<in.rows();i++)
eval( in.row(i).transpose(), out.row(i).transpose() );
};
};
The compiler Error looks like:
In file included from main.cc:2:0:
../tmp.hpp: In member function ‘virtual void eval(Eigen::Ref<const Eigen::Matrix<float, -1, -1, 1> >, Eigen::Ref<Eigen::Matrix<float, -1, -1, 1> >)’:
../tmp.hpp:36:62: error: call of overloaded ‘eval(Eigen::DenseBase<Eigen::Block<const Eigen::Ref<const Eigen::Matrix<float, -1, -1, 1> >, 1, -1, true> >::ConstTransposeReturnType, Eigen::Transpose<Eigen::Block<Eigen::Ref<Eigen::Matrix<float, -1, -1, 1> >, 1, -1, true> >)’ is ambiguous
eval( in.row(i).transpose(), out.row(i).transpose() );
^
../tmp.hpp:25:7: note: candidate: virtual void eval(Eigen::Ref<const Eigen::Matrix<float, -1, 1> >, Eigen::Ref<Eigen::Matrix<float, -1, 1> >)
void eval(const Ref<const Matrix<float, Dynamic, 1>> input,
^
../tmp.hpp:32:7: note: candidate: virtual void eval(Eigen::Ref<const Eigen::Matrix<float, -1, -1, 1> >, Eigen::Ref<Eigen::Matrix<float, -1, -1, 1> >)
void eval(const Ref<const Matrix<float, Dynamic, Dynamic, RowMajor>> input,
^
make: *** [main.o] Error 1
I found this. The types doesn't match, but for me it is not clear how to solve this elegant ( without template's because of the base class )

Indeed, when calling eval with vectors, both overloads can be matched. One solution would be to rename the two overloads to distinct names (e.g., evalVec and evalMat), and add a thin template method dispatching to the correct one:
template<typename A, typename B>
void eval(const MatrixBase<A> &a, MatrixBase<B> &b,
typename enable_if<A::IsVectorAtCompile,void*>::type = 0) {
this->evalVec(a.derived(),b.derived());
}
template<typename A, typename B>
void eval(const MatrixBase<A> &a, MatrixBase<B> &b,
typename enable_if<!A::IsVectorAtCompile,void*>::type = 0) {
this->evalMat(a.derived(),b.derived());
}

Related

function pointers and enum in C

I am looking for a fancy way to link function pointers and enums.
In my case I have a message queue that holds a event id and some data associated with the event.
some simple pseudo code:
event=(eid, data)
switch(eid) {
case eid1:
handler1(data);
break;
case edi2:
handler2(data);
break;
}
Now I like to do some optimization. If the event id has the value of the function called inside of the switch case statement I can save the switch case decode by preserving a nice readability of the code.
event=(eid, data)
eid(data)
Now if I am putting it into an example like:
static void abc(void * p) {
}
static void abc2(void * p) {
}
enum eventId {
eid1 = abc,
eid2 = abc2
} xyz;
My compiler tells:
error: enumerator value for 'eid1' is not an integer constant eid1 = abc
What is absolutely right.
Any ideas how to solve that problem?
Use an array of function pointers, and use the enum as the index.
typedef void (*handler_func)(void *);
handler_func event_handlers[] = { abc, abc2 };
enum eventId {
eid1 = 0,
eid2 = 1,
eid_max
}
if (eid < eid_max) event_handlers[eid](data);
enums cannot be linked with other data in C, but the preprocessor can generate code for you in the form of X-Macros.
#include <stdio.h>
typedef void (*handler_func)(void *);
static void handler1(void *const param) {
printf("Event 1: %p.\n", param);
}
static void handler2(void *const param) {
printf("Event 2: %p.\n", param);
}
#define EVENT(X) \
X(EID1, &handler1), \
X(EID2, &handler2)
#define PARAMA(A, B) A
#define PARAMB(A, B) B
#define STRINGISEA(A, B) #A
enum Event { EVENT(PARAMA) };
static const handler_func event_handlers[] = { EVENT(PARAMB) };
static const char *const event_strings[] = { EVENT(STRINGISEA) };
/* Everything will be the same size, pick one. */
static const size_t event_size = sizeof event_strings / sizeof *event_strings;
int main(void) {
size_t i;
void *const param = (void *)0x100;
for(i = 0; i < event_size; i++) {
printf("Calling %s.\n", event_strings[i]);
event_handlers[i](param);
}
return 0;
}
Gives,
Calling EID1.
Event 1: 0x100.
Calling EID2.
Event 2: 0x100.
The advantage of this implementation is it's a single source of truth; if one decided to add more events, they will only need to be added in one spot. The disadvantage is it's hard to read.
As an extension to the answer of #Barmar, you can use a technique called X macro, to keep corresponding (eid, handler) pairs in order. Note that you need only to change the definition of LIST_OF_EVENTS macro, adding or deleting pairs as needed.
void handler1(void*);
void handler2(void*);
void handler3(void*);
#define LIST_OF_EVENTS X(eid1, handler1), X(eid2, handler2), X(eid3, handler3)
#define X(id, x) id
enum evID { LIST_OF_EVENTS };
#undef X
#define X(x, handler) handler
void (*handlers[])(void*) = { LIST_OF_EVENTS };
#undef X
int get_event(void**);
void event_loop(void)
{
for (;;) {
void *data;
int eid = get_event(&data);
handlers[eid](data);
}
}
Macro defitions expand to
enum evID { eid1, eid2, eid3 };
void (*handlers[])(void*) = { handler1, handler2, handler3 };

How can an array of structs be initialized using a const struct in global scope?

I want to use code similar to the following (but a lot more complex - this is a simplified example) to initialize an array of structures, but during compilation I get the error "expression must have a constant value".
typedef struct
{
int x;
int y;
} windowStruct_t;
static const windowStruct_t windowStructInit =
{
.x = 3,
.y = 5,
};
// These get defined differently at times. This is simplified for the example.
#define NUM_ARRAY_ELEMENTS (2)
#define REPEAT_NUM_ARRAY_ELEMENTS_TIMES(x) (x),(x)
// The following line causes the error "expression must have a constant value" twice.
windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] =
{ REPEAT_NUM_ARRAY_ELEMENTS_TIMES( windowStructInit ) };
void someFunction( void )
{
volatile int x = windowStruct[0].x;
}
void anotherFunction( void )
{
volatile int y = windowStruct[1].y;
}
Manually expanding the macro and replacing the line that causes the error with the following gives the same result:
windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] =
{ windowStructInit, windowStructInit };
But this compiles without error:
windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] =
{ { .x = 3, .y = 5 }, { .x = 3, .y = 5 } };
If I move the array declaration inside of function scope, it compiles without errors (I am ignoring the fact that someFunction() and anotherFunction() now access different arrays and that their lifetimes are different):
void someFunction( void )
{
windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] =
{ REPEAT_NUM_ARRAY_ELEMENTS_TIMES( windowStructInit ) };
volatile int x = windowStruct[0].x;
}
void anotherFunction( void )
{
windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] =
{ REPEAT_NUM_ARRAY_ELEMENTS_TIMES( windowStructInit ) };
volatile int y = windowStruct[1].y;
}
Leaving the array declarations inside of function scope, if they are declared to be "static", the error message comes back:
void someFunction( void )
{
static windowStruct_t windowStruct[ NUM_ARRAY_ELEMENTS ] =
{ REPEAT_NUM_ARRAY_ELEMENTS_TIMES( windowStructInit ) };
volatile int x = windowStruct[0].x;
}
So it seems that when the arrays are declared as automatic variables (on the stack) that they can be initialized in a way that isn't allowed when the memory allocation is static (whether inside function scope or in global scope where the allocation is static even without the "static" keyword). Is there a way to initialize the array in global scope using a const struct as in the original example?
I am using C, not C++. I don't want to use dynamic memory allocation. The compiler is TI's ARM compiler V16.6.0.STS as included in their Code Composer Studio environment.
A const object is not a C constant. Instead use constants which is required for non-automatic storage objects.
Define an initializer { .x = 3, .y = 5 }
typedef struct windowStruct_s {
int x;
int y;
} windowStruct_t;
#define windowStruct_t_default_initializer { .x = 3, .y = 5 }
#define NUM_ARRAY_ELEMENTS (2)
#define REPEAT_NUM_ARRAY_ELEMENTS_TIMES(x) x, x /* no () */
windowStruct_t windowStruct[NUM_ARRAY_ELEMENTS] = {
REPEAT_NUM_ARRAY_ELEMENTS_TIMES(windowStruct_t_default_initializer) };
int someFunction(void) {
volatile int x = windowStruct[0].x;
return x;
}
int anotherFunction(void) {
volatile int y = windowStruct[1].y;
return y;
}

directx 11 LNK error 2005, 2019 and 1120

i'm following a book on how to program with driectx 11 but i still got 3 error even though i've programmed it to be exactly the same and checked for diffrences for almost a full day now. i've got 3 errors
error LNK1120: 1 unresolved externals C:\Users\Me\documents\visual studio 2013\Projects\TestX engine\Debug\TestX engine.exe 1 1 TestX engine
Error 2 error LNK2019: unresolved external symbol _D3DX11CreateEffectFromMemory#20 referenced in function "private: void __thiscall BoxApp::BuildFX(void)" (?BuildFX#BoxApp##AAEXXZ) C:\Users\Me\documents\visual studio 2013\Projects\TestX engine\TestX engine\Box.obj TestX engine
Error 1 error LNK2005: _WinMain#16 already defined in Box.obj C:\Users\Me\documents\visual studio 2013\Projects\TestX engine\TestX engine\InitDirect3D.obj TestX engine
and my code for the app is:
class BoxApp : public Framework_App
{
public:
BoxApp(HINSTANCE hInstance);
~BoxApp();
bool Init();
void OnResize();
void UpdateScene( float dt);
void DrawScene();
void OnMouseDown(WPARAM btnState, int x, int y);
void OnMouseUp(WPARAM btnState, int x, int y);
void OnMouseMove(WPARAM btnState, int x, int y);
private:
void BuildGeometryBuffers();
void BuildFX();
void BuildVertexlayout();
ID3D11Buffer* mBoxVB;
ID3D11Buffer* mBoxIB;
ID3DX11Effect* mFX;
ID3DX11EffectTechnique* mTech;
ID3DX11EffectMatrixVariable* mfxWorldViewProj;
ID3D11InputLayout* inputLayout;
XMFLOAT4X4 mWorld;
XMFLOAT4X4 mView;
XMFLOAT4X4 mProj;
float mTheta, mPhi, mRadius;
POINT mLastMousePos;
};
the problem should be somewhere around these parts, but i can't find them:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE PrevhInstance, PSTR cmdLine, int showCmd){
BoxApp theApp(hInstance);
if (!theApp.Init())
{
return 0;
}
return theApp.App_Run();
}
and:
void BoxApp::BuildFX()
{
DWORD shaderFlags = 0;
ID3D10Blob * compiledShader;
ID3D10Blob * compiledShaderMsgs;
HRESULT hr = D3DX11CompileFromFile((LPSTR)"mColor.fx", 0, 0, 0, "fx_5_0", shaderFlags, 0, 0, &compiledShader, &compiledShaderMsgs, 0);
if (compiledShaderMsgs != 0)
{
MessageBoxA(0, (char*)compiledShaderMsgs->GetBufferPointer(), 0, 0);
ReleaseCOM(compiledShaderMsgs);
}
D3DX11CreateEffectFromMemory(compiledShader->GetBufferPointer(), compiledShader->GetBufferSize(), 0, MainD3DDevice, &mFX);
ReleaseCOM(compiledShader);
mTech = mFX->GetTechniqueByName("ColorTech");
mfxWorldViewProj = mFX->GetVariableByName("gWorldViewProj")->AsMatrix();
}
in the second bit in particulary this: D3DX11CreateEffectFromMemory(compiledShader->GetBufferPointer(), compiledShader->GetBufferSize(), 0, MainD3DDevice, &mFX);
thank you beforehand, i really appreciate it.

Declaring structure to avoid mixed declarations and code

I'm compiling with -Wdeclaration-after-statement and I get the following warning:
ISO C90 forbids mixed declarations and code
This is because I need to perform certain operations before filling the array.
I wonder what would be a good way or alternative to initialize and declare cars so this warning can be avoided.
The code in question looks something like this:
int my_func() {
typedef struct Car_ {
char *brand;
int amount;
int color;
} Car;
int fixed = 0;
int total1 = getAmountBase(brand1);
int total2 = getAmountSub(brand2);
int total3 = getAmountBase(brand3);
int total4 = getAmountSub(brand4);
int grand = getAmountBase(brand7);
// more operations...
if (grand7 != NULL) {
grand7 = calcBase(grand7, total6);
fixed = addGrand(grand7);
}
Car cars[] = { // warning here.
{"brand1", total1, RED},
{"brand2", total2, RED},
{"brand3", total3, RED},
{"brand4", total4, RED},
{"brand7", fixed, RED},
};
// ...
}
Declare it up front and assign the computed parts later:
Car cars[] = {
{"brand1", -1, RED},
{"brand2", -1, RED},
{"brand3", -1, RED},
{"brand4", -1, RED},
{"brand7", -1, RED},
};
...
cars[0].amount = total1;
cars[1].amount = total2;
/* etc */
Or, if suitable, compile with -std=c99.

C2061 Syntax Error (identifier)

1>cb.c(51): error C2061: syntax error : identifier 'SaveConfiguration'
1>cb.c(51): error C2059: syntax error : ';'
1>cb.c(51): error C2059: syntax error : 'type'
1>cb.c(52): error C2061: syntax error : identifier 'LoadConfiguration'
1>cb.c(52): error C2059: syntax error : ';'
1>cb.c(52): error C2059: syntax error : 'type'
1>cb.c(122): error C2061: syntax error : identifier 'SaveConfiguration'
1>cb.c(122): error C2059: syntax error : ';'
1>cb.c(122): error C2059: syntax error : 'type'
1>cb.c(127): error C2061: syntax error : identifier 'LoadConfiguration'
1>cb.c(127): error C2059: syntax error : ';'
1>cb.c(127): error C2059: syntax error : 'type'
1>
1>Build FAILED.
It's just a single .c file in the project. Here's the code:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <tchar.h>
typedef struct _Configuration
{
int KeyActivate;
int BlockWidth;
int BlockHeight;
double HueStart;
double HueEnd;
double SaturationStart;
double SaturationEnd;
double ValueStart;
double ValueEnd;
} Configuration;
typedef struct _DIBSection
{
HDC ScreenDC;
HDC WindowDC;
HDC MemoryDC;
HBITMAP ScreenBMPHandle;
BITMAP ScreenBMP;
} DIBSection;
typedef struct _Thread
{
HANDLE Handle;
unsigned Id;
} Thread;
typedef struct _Window
{
HANDLE Handle;
HDC DC;
int Width;
int Height;
int Top;
int Left;
} Window;
__declspec ( dllexport ) int Initialize ( void );
unsigned __stdcall Start ( void * Arguments );
void LoadDefaultConfiguration ( Configuration * Config );
bool SaveConfiguration ( Configuration * Config, LPTSTR FilePath );
bool LoadConfiguration ( Configuration * Config, LPTSTR FilePath );
Thread MainThread;
Window Screen;
Configuration Settings;
BOOL WINAPI DllMain ( HINSTANCE Instance, DWORD Reason, LPVOID Reserved )
{
switch ( Reason )
{
case DLL_PROCESS_ATTACH:
// TODO: Load settings from file
LoadDefaultConfiguration ( & Settings );
// Create main thread
MainThread.Handle = (HANDLE) _beginthreadex (
NULL,
0,
Start,
NULL,
0,
& MainThread.Id
);
if ( MainThread.Handle )
{
SetThreadPriority ( MainThread.Handle, THREAD_PRIORITY_BELOW_NORMAL );
}
else
{
MessageBox ( NULL, L"Unable to create main thread; exiting", L"Error", MB_OK );
ExitProcess ( 0 );
}
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
__declspec ( dllexport ) int Initialize ( void )
{
return 1;
}
unsigned __stdcall Start ( void * Arguments )
{
return 1;
}
void LoadDefaultConfiguration ( Configuration * Config )
{
Config->BlockHeight = 50;
Config->BlockWidth = 100;
Config->HueEnd = 0.00;
Config->HueStart = 0.00;
Config->KeyActivate = VK_SHIFT;
Config->SaturationEnd = 0.00;
Config->SaturationStart = 0.00;
Config->ValueEnd = 0.00;
Config->ValueStart = 0.00;
}
bool SaveConfiguration ( Configuration * Config, LPTSTR FilePath )
{
return true;
}
bool LoadConfiguration ( Configuration * Config, LPTSTR FilePath )
{
return true;
}
Line 51 is
bool SaveConfiguration ( Configuration * Config, LPTSTR FilePath );
bool is not a C type.
I do suspect BOOL is defined somewhere.
Same goes for the usage of true and false.
Actually, bool is a valid type (well, a macro actually) in the C99 standard, assuming you are using a recent compiler. You need to add:
#include <stdbool.h>
Note that bool is not valid in the older ANSI, C89, C90 etc variants of the C standards.
As highlighted by JeremyP in the comments, Microsoft's C compiler still lacks proper support for C99 features.
Which leaves three alternatives:
Treat it as C++, not C; because C++ has bool as a built-in type
Create your own bool implementation
Re-write the code to avoid using bool
For option 2 something like this would work, but it's an ugly work-around:
typedef short bool;
#define true 1
#define false 0

Resources