Spectral
Spectral

Reputation: 717

Imitate OpenCL float2 type in C++

In OpenCL C99 we can write this to create a new instance of 'float2' :

float f = (float2)(1.f, 2.f);

My problem is that I need to use the EXACT SAME code in C++, for this I have create a new class float2, but it seems that the following operator is not called in this case :

inline float2 operator()(const float a, const float b) { return float2(a, b); }

Does someone has an idea for a solution ?

Upvotes: 3

Views: 1703

Answers (3)

Manu343726
Manu343726

Reputation: 14174

The Standard Library contains a header <complex>, which defines a template std::complex dessigned to do arithmetic computations with complex numbers.
That complex numbers are represented as pairs of floating-point values (The real part and the imaginary part), so it could be used to emulate your float2 type.

If you define an alias float2 you could emulate your exact syntax via C style casting:

#include <complex>

typedef std::complex<float> float2;

int main()
{
    float2 f = (float2)(1.0,2.0);
}

As you can see, you can emulate that syntax using standard C++ facilities only, not custom tricks.

Here is a running example.

Upvotes: 0

TC.
TC.

Reputation: 4183

I don't believe this is possible. The line float2 f = (float2)(1.f, 2.f); can be interpreted in two ways:

  1. If float2 is a type, cast the result of (1.f, 2.f) (an expression using the comma operator, returning a float) to a float2. Since there is no cast from float to float2, this fails.
  2. If float2 is a function/functor, execute func2 using the provided two arguments.

Using the former interpretation, we could try to add the conversion operator like you tried, which would have to be a conversion from float to float2, since the result of (1.f, 2.f) is a float (2.f). We would not have access to the first argument in this conversion though (which is lost after the comma operator), so this wouldn't get us anywhere.

Using the latter interpretation, we can write something along the lines of:

detail::float2 float2(float x, float y)
{
    detail::float2 result(x, y);
    return result;
}

int main(int argc, char **argv)
{
    detail::float2 f = (float2)(1.f, 2.f);
    return 0;
}

Note that I've put the float2 struct (omitted for brevity) in a namespace called detail, which was necessary in order to resolve the ambiguity caused by having both a type and a function named float2 in the same namespace. Sadly, I don't think there is a way around this and it is the closest we can get. You won't be able to use the exact same code in OpenCL and C++ though.

Upvotes: 0

Tom Fenech
Tom Fenech

Reputation: 74615

Following on from jprice's comment, if you can change the syntax of your OpenCL code, you could make this work in both languages by defining a simple struct in your C++ code:

struct float2 {
  float x, y;
  // define operators here
};

then instead of using the "cast-style" syntax above, you could do:

float2 f;
f.x = 1.f; f.y = 2.f;

which would work in both.

Upvotes: 1

Related Questions