Unable to initialize std::array of std::complex

Recommended Posts

I have some issues with this code:

std::vector< std::array<std::complex<float>,3> > &hexWaves;

...

std::vector< std::pair< int, std::array<std::complex<float>,3> > > boundary;

// nothing works, results are always (0,0):
std::array< std::complex<float>, 3 > b {(boundaryStrength, 0.f), (boundaryStrength, 0.f), (boundaryStrength, 0.f)};
//std::array< std::complex<float>, 3 > b { {(boundaryStrength, 0.f), (boundaryStrength, 0.f), (boundaryStrength, 0.f)} };
//std::array< std::complex<float>, 3 > b = {(boundaryStrength, 0.f), (boundaryStrength, 0.f), (boundaryStrength, 0.f)};

// this would work, resulting in (boundaryStrength, 0):
//std::array< std::complex<float>, 3 > b {(0.f, boundaryStrength), (0.f, boundaryStrength), (0.f, boundaryStrength)};

for (int vI=0; vI<mesh.GetVertexCount(); vI++) if (vertexSingularityValence[vI] != 6)
{
boundary.push_back(std::make_pair(vI, b));
hexWaves[vI] = b;
ImGui::Text("Baoundary wave [%i][0]: %f %f", vI, hexWaves[vI][0].real(), hexWaves[vI][1].imag());
}

Only with wrong syntax i get the expected result of setting the real part to given number, and imaginary part to zero.

I have used similar code quite often like in the first uncommented line, but now i guess there is some catch. What is it?

The last commented line works, but it's clearly wrong.

I'm very confused...

Share on other sites
Posted (edited)

When the compiler evaluates (boundaryStrength, 0.f) it doesn't know you are trying to build a complex number, so it interprets it as using operator ",", which simply evaluates the left side, then the right side, then the whole expression evaluates to the right side.

This should work:

  std::array<std::complex<float>,3> b {
std::complex<float>(boundaryStrength, 0.f),
std::complex<float>(boundaryStrength, 0.f),
std::complex<float>(boundaryStrength, 0.f)
};

EDIT: One more thing. The line with (0.f, boundaryStrength) was "working" because operator "," evaluates to the right side, which was then used in the constructor of std::complex<float> that takes a float and interprets it as a real number.

Edited by alvaro

Share on other sites

Makes all sense, thanks!

I'll avoid such lazy inits in the future. Paranoia over laziness!

Share on other sites

Since they are actually real numbers, you can directly say boundarySource' and it will work.

Share on other sites

Yeah you're right, changed it accordingly.

By the way, the geometry processing stuff i work on was ideal to use complex numbers for rotations as you showed me a while back.

It's about crossfields and waves to drive quad remeshing, but visually and for fun linefields are much more interesting:

Share on other sites

When in doubt... add more braces... (std::array is an aggregate of a C array of complex numbers):

std::array<std::complex<float>, 3 > b = {{
{boundaryStrength, 0.0f},
{boundaryStrength, 0.0f},
{boundaryStrength, 0.0f}
}};

This should work. Or using literals (which would be so much nicer without having to plaster using namespace statements everywhere you want to use them):

using namespace std::complex_literals;
std::array<std::complex<float>, 3 > b = {
boundaryStrength + 0if,
boundaryStrength + 0if,
boundaryStrength + 0if
};`

Strangely enough, no extra braces necessary anymore.

Create an account

Register a new account

• 10
• 10
• 12
• 10
• 33