🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

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

Started by
5 comments, last by Eternal 5 years, 2 months ago

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... :S

Advertisement

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.

Makes all sense, thanks!

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

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

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: :D

image.png.8628f10b084ec92a8b2ac9d344cbde32.png

 

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.

This topic is closed to new replies.

Advertisement