Tuesday, April 11, 2017

Digest for comp.lang.c++@googlegroups.com - 18 updates in 3 topics

hsmyers@gmail.com: Apr 10 06:41PM -0700

On Monday, April 10, 2017 at 5:10:07 PM UTC-6, Chris M. Thomasson wrote:
> ratio? Any ideas?
 
> Will post more context later on tonight or tommorw.
 
> :^)
 
I'll give it a go tomorrow! Right now I'm working on a project to check out nearly a thousand proposed fractal formulas *grin* I'm writing a parser for them to rewrite as Ulta Fractal formulas which allows a quick worthiness check…
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 10 07:35PM -0700


> I'll give it a go tomorrow! Right now I'm working on a project to check out
> nearly a thousand proposed fractal formulas *grin* I'm writing a parser for
> them to rewrite as Ulta Fractal formulas which allows a quick worthiness check…
 
Nice! I need a good parser for fractal formulas. :^)
Christian Gollwitzer <auriocus@gmx.de>: Apr 11 07:41AM +0200

Am 11.04.17 um 01:09 schrieb Chris M. Thomasson:
> std::cos(angle_base + angle) * radius,
> std::sin(angle_base + angle) * radius
> };
 
 
While this is correct, I think that the following is easier and should
run faster:
 
std::vector<ct_complex> myroots;
ct_complex baseroot = std::pow(z, 1.0/p);
myroots.push_back(baseroot);
 
ct_complex root = baseroot;
ct_complex phasor = baseroot / std::abs(baseroot);
for (int i=1; i<n; i++) {
root *= phasor;
myroots.push_back(root);
}
 
(untested)
 
This algorithm saves the computation of 2*(n-1) transcendental
functions. Concerning accuracy, your algorithm is more accurate if you
compute roots of very high order (say 1e10) - probably not for useful
cases.
 
Christian
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 11 08:23AM +0200

On 11-Apr-17 7:41 AM, Christian Gollwitzer wrote:
> functions. Concerning accuracy, your algorithm is more accurate if you
> compute roots of very high order (say 1e10) - probably not for useful
> cases.
 
I still don't understand how rotation, and thereby the structure
(metric) of our physical environment, emerges in complex arithmetic.
 
It's amazing.
 
It's simple to show that `i` multiplied by itself goes round through
four positions (i, -1, -i, 1, ...), and then that with e.g. the point 45
degrees up right, the powers give a rotation through eight positions,
including `i` so that it can be identified with the square root of `i`,
and so on. But what /causes/ this behavior eludes me. And even though
I'm old and pretty stupid now, I have been good at math, and I believe
I've been thinking about this also in my younger days.
 
 
Cheers!,
 
- Alf (baffled, again :) )
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 10 04:09PM -0700

The goal of this crude sample code is to take the n-ary roots of a
complex number. Iterating a complex number z to all of its z^(1/n)
roots. This code derives the polar form from z, and iterates all of the
roots. This is an essential part of providing the ability of storing
n-ary tokens in a set of iterated roots. We can map the n roots, to a
token table, and store data. I will explain more later, however, please
take a look at the code, run it, tear it apart, and give me pointers on
how to make it better, please? Thank you all for your time. The function
at the heart of this is the function ct_roots that breaks apart a
complex number into its n-ary roots. Here is the code:
 
______________________________
#include <complex>
#include <iostream>
#include <vector>
#include <limits>
#include <cstdint> // want to work with 64-bit numbers
#include <cassert> // want to sanity check run time...
 
 
// Well, I need some consistent typenames... ;^)
typedef std::int64_t ct_int;
typedef std::uint64_t ct_uint;
typedef double ct_float;
typedef std::numeric_limits<ct_float> ct_float_nlim;
typedef std::complex<ct_float> ct_complex;
typedef std::complex<ct_uint> ct_complex_uint;
typedef std::vector<ct_complex> ct_complex_vec;
 
#define CT_PI 3.14159265358979323846
 
 
// Round up and convert the real and imaginary
// parts of z to unsigned integers of type ct_uint
// return a complex number with unsigned integer parts
ct_complex_uint
ct_round_uint(
ct_complex const& z
) {
ct_uint re = (ct_uint)std::floor(std::abs(z.real()) + .5);
ct_uint im = (ct_uint)std::floor(std::abs(z.imag()) + .5);
return ct_complex_uint(re, im);
}
 
 
// the integer p shall not be zero
// create abs(p) roots of z wrt z^(1/p);
// store them in out, and return the average error.
ct_float
ct_roots(
ct_complex const& z,
ct_int p,
ct_complex_vec& out
) {
assert(p != 0);
 
// Gain the basics
ct_float radius = std::pow(std::abs(z), 1.0 / p);
ct_float angle_base = std::arg(z) / p;
ct_float angle_step = (CT_PI * 2.0) / p;
 
// Setup the iteration
ct_uint n = std::abs(p);
ct_float avg_err = 0.0;
 
// Calculate the n roots...
for (ct_uint i = 0; i < n; ++i)
{
// our angle
ct_float angle = angle_step * i;
 
// our point
ct_complex c = {
std::cos(angle_base + angle) * radius,
std::sin(angle_base + angle) * radius
};
 
// output data
out.push_back(c);
 
// Raise our root the the power...
ct_complex raised = std::pow(c, p);
ct_complex_uint raised_rounded = ct_round_uint(raised);
 
// Output...
std::cout << "ct_roots::raised[" << i << "]:" <<
raised << "\n";
std::cout << "ct_roots::raised_rounded[" << i << "]:" <<
raised_rounded << "\n";
std::cout << "___________________________________\n";
 
 
// Sum up the Go% damn floating point errors!
avg_err = avg_err + std::abs(raised - z);
 
}
 
// gain the average error sum... ;^o
return avg_err / n;
}
 
 
 
 
int main()
{
std::cout.precision(ct_float_nlim::max_digits10);
 
{
// Our origin point z
ct_complex z = { 94143178827, 0 };
 
std::cout << "z:" << z << " - " << std::abs(z) << "\n";
std::cout << "**********************************************\n\n";
 
// The call to ct_roots...
ct_complex_vec roots;
ct_float avg_err = ct_roots(z, 23, roots);
std::cout << "\n\navg_err:" << avg_err << "\n";
 
// Output
std::cout << "___________________________________\n";
for (unsigned int i = 0; i < roots.size(); ++i)
{
ct_complex& root = roots[i];
 
std::cout << "root[" << i << "]:" << root << " - " <<
std::abs(root) << "\n";
}
std::cout << "___________________________________\n";
}
 
// Fin...
std::cout << "\n\nFin, hit <ENTER> to exit...\n";
std::fflush(stdout);
std::cin.get();
 
return 0;
}
______________________________
 
 
Can you run this? BTW, what about possibly reducing the average error
ratio? Any ideas?
 
Will post more context later on tonight or tommorw.
 
:^)
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 11 12:13PM -0700

On 4/10/2017 10:41 PM, Christian Gollwitzer wrote:
> functions. Concerning accuracy, your algorithm is more accurate if you
> compute roots of very high order (say 1e10) - probably not for useful
> cases.
 
Here is a function I wrote that uses your algorithm:
_________________________________
ct_float
cg_roots(
ct_complex const& z,
ct_int p,
ct_complex_vec& out
) {
assert(p != 0);
 
/*
Per: Christian Gollwitzer's untested code at:
https://groups.google.com/d/msg/comp.lang.c++/05XwgswUnDg/gm_uqbcwAgAJ
 
std::vector<ct_complex> myroots;
ct_complex baseroot = std::pow(z, 1.0/p);
myroots.push_back(baseroot);
 
ct_complex root = baseroot;
ct_complex phasor = baseroot / std::abs(baseroot);
for (int i=1; i<n; i++) {
root *= phasor;
myroots.push_back(root);
}
*/
 
// Did I fuc% up his code! Read here:
 
ct_complex baseroot = std::pow(z, 1.0 / p);
out.push_back(baseroot);
 
ct_complex root = baseroot;
ct_complex phasor = baseroot / std::abs(baseroot);
 
ct_uint n = std::abs(p);
ct_float avg_err = 0.0;
 
for (ct_uint i = 1; i < n; ++i)
{
root *= phasor;
out.push_back(root);
 
// Raise our root the the power...
ct_complex raised = std::pow(root, p);
ct_complex_uint raised_rounded = ct_round_uint(raised);
 
// Output...
std::cout << "ct_roots_fast::raised[" << i << "]:" <<
raised << "\n";
std::cout << "ct_roots_fast::raised_rounded[" << i << "]:" <<
raised_rounded << "\n";
std::cout << "___________________________________\n";
 
// Sum up the Go% damn floating point errors!
avg_err = avg_err + std::abs(raised - z);
}
 
// gain the average error sum... ;^o
return avg_err / n;
}
_________________________________
 
When I change the call in main to ct_roots to cg_roots in main wrt the
function in:
 
_________________________________
int main()
{
std::cout.precision(ct_float_nlim::max_digits10);
 
{
// Our origin point z
ct_complex z = { 94143178827, 0 };
 
std::cout << "z:" << z << " - " << std::abs(z) << "\n";
std::cout << "**********************************************\n\n";
 
// The call to ct_roots...
ct_complex_vec roots;
//ct_float avg_err = ct_roots(z, 23, roots);
ct_float avg_err = cg_roots(z, 23, roots);
std::cout << "\n\navg_err:" << avg_err << "\n";
 
// Output
std::cout << "___________________________________\n";
for (unsigned int i = 0; i < roots.size(); ++i)
{
ct_complex& root = roots[i];
 
std::cout << "root[" << i << "]:" << root << " - " <<
std::abs(root) << "\n";
}
std::cout << "___________________________________\n";
}
 
// Fin...
std::cout << "\n\nFin, hit <ENTER> to exit...\n";
std::fflush(stdout);
std::cin.get();
 
return 0;
}
_________________________________
 
 
I get the following incorrect output in the sense that it does show all
of the roots:
 
 
z:(94143178827,0) - 94143178827
**********************************************
 
ct_roots_fast::raised[1]:(94143178827,0)
ct_roots_fast::raised_rounded[1]:(94143178827,0)
___________________________________
ct_roots_fast::raised[2]:(94143178827,0)
ct_roots_fast::raised_rounded[2]:(94143178827,0)
___________________________________
ct_roots_fast::raised[3]:(94143178827,0)
ct_roots_fast::raised_rounded[3]:(94143178827,0)
___________________________________
ct_roots_fast::raised[4]:(94143178827,0)
ct_roots_fast::raised_rounded[4]:(94143178827,0)
___________________________________
ct_roots_fast::raised[5]:(94143178827,0)
ct_roots_fast::raised_rounded[5]:(94143178827,0)
___________________________________
ct_roots_fast::raised[6]:(94143178827,0)
ct_roots_fast::raised_rounded[6]:(94143178827,0)
___________________________________
ct_roots_fast::raised[7]:(94143178827,0)
ct_roots_fast::raised_rounded[7]:(94143178827,0)
___________________________________
ct_roots_fast::raised[8]:(94143178827,0)
ct_roots_fast::raised_rounded[8]:(94143178827,0)
___________________________________
ct_roots_fast::raised[9]:(94143178827,0)
ct_roots_fast::raised_rounded[9]:(94143178827,0)
___________________________________
ct_roots_fast::raised[10]:(94143178827,0)
ct_roots_fast::raised_rounded[10]:(94143178827,0)
___________________________________
ct_roots_fast::raised[11]:(94143178827,0)
ct_roots_fast::raised_rounded[11]:(94143178827,0)
___________________________________
ct_roots_fast::raised[12]:(94143178827,0)
ct_roots_fast::raised_rounded[12]:(94143178827,0)
___________________________________
ct_roots_fast::raised[13]:(94143178827,0)
ct_roots_fast::raised_rounded[13]:(94143178827,0)
___________________________________
ct_roots_fast::raised[14]:(94143178827,0)
ct_roots_fast::raised_rounded[14]:(94143178827,0)
___________________________________
ct_roots_fast::raised[15]:(94143178827,0)
ct_roots_fast::raised_rounded[15]:(94143178827,0)
___________________________________
ct_roots_fast::raised[16]:(94143178827,0)
ct_roots_fast::raised_rounded[16]:(94143178827,0)
___________________________________
ct_roots_fast::raised[17]:(94143178827,0)
ct_roots_fast::raised_rounded[17]:(94143178827,0)
___________________________________
ct_roots_fast::raised[18]:(94143178827,0)
ct_roots_fast::raised_rounded[18]:(94143178827,0)
___________________________________
ct_roots_fast::raised[19]:(94143178827,0)
ct_roots_fast::raised_rounded[19]:(94143178827,0)
___________________________________
ct_roots_fast::raised[20]:(94143178827,0)
ct_roots_fast::raised_rounded[20]:(94143178827,0)
___________________________________
ct_roots_fast::raised[21]:(94143178827,0)
ct_roots_fast::raised_rounded[21]:(94143178827,0)
___________________________________
ct_roots_fast::raised[22]:(94143178827,0)
ct_roots_fast::raised_rounded[22]:(94143178827,0)
___________________________________
 
 
avg_err:0
___________________________________
root[0]:(3,0) - 3
root[1]:(3,0) - 3
root[2]:(3,0) - 3
root[3]:(3,0) - 3
root[4]:(3,0) - 3
root[5]:(3,0) - 3
root[6]:(3,0) - 3
root[7]:(3,0) - 3
root[8]:(3,0) - 3
root[9]:(3,0) - 3
root[10]:(3,0) - 3
root[11]:(3,0) - 3
root[12]:(3,0) - 3
root[13]:(3,0) - 3
root[14]:(3,0) - 3
root[15]:(3,0) - 3
root[16]:(3,0) - 3
root[17]:(3,0) - 3
root[18]:(3,0) - 3
root[19]:(3,0) - 3
root[20]:(3,0) - 3
root[21]:(3,0) - 3
root[22]:(3,0) - 3
___________________________________
 
 
Fin, hit <ENTER> to exit...
 
 
 
 
Notice the roots are all (3, 0)? This is not correct. Please try to find
an error I may have created in my implementation of your code Christian
Gollwitzer, wrt the cg_roots function. Sorry if I fuc%ed it up man... ;^o
 
 
Fwiw, here is the output I get from using the original, slow trig
infested original of mine:
 
z:(94143178827,0) - 94143178827
**********************************************
 
ct_roots::raised[0]:(94143178827,0)
ct_roots::raised_rounded[0]:(94143178827,0)
___________________________________
ct_roots::raised[1]:(94143178826.999603,6.0557511273702414e-05)
ct_roots::raised_rounded[1]:(94143178827,0)
___________________________________
ct_roots::raised[2]:(94143178827.000259,-4.6116857044817097e-05)
ct_roots::raised_rounded[2]:(94143178827,0)
___________________________________
ct_roots::raised[3]:(94143178827.000259,-6.9175285567225643e-05)
ct_roots::raised_rounded[3]:(94143178827,0)
___________________________________
ct_roots::raised[4]:(94143178827.000259,-9.2233714089634195e-05)
ct_roots::raised_rounded[4]:(94143178827,0)
___________________________________
ct_roots::raised[5]:(94143178826.999603,-0.00044975590179648512)
ct_roots::raised_rounded[5]:(94143178827,0)
___________________________________
ct_roots::raised[6]:(94143178826.999603,-0.00013835057113445031)
ct_roots::raised_rounded[6]:(94143178827,0)
___________________________________
ct_roots::raised[7]:(94143178827.000259,-0.00016140899965685982)
ct_roots::raised_rounded[7]:(94143178827,0)
___________________________________
ct_roots::raised[8]:(94143178827.000259,-0.00018446742817926839)
ct_roots::raised_rounded[8]:(94143178827,0)
___________________________________
ct_roots::raised[9]:(94143178827.000259,-0.00087645337507056794)
ct_roots::raised_rounded[9]:(94143178827,0)
___________________________________
ct_roots::raised[10]:(94143178827.000259,-0.00089951180359297653)
ct_roots::raised_rounded[10]:(94143178827,0)
___________________________________
ct_roots::raised[11]:(94143178827.000259,0.00041528480462239701)
ct_roots::raised_rounded[11]:(94143178827,0)
___________________________________
ct_roots::raised[12]:(94143178827.000259,-0.00041528480462239701)
ct_roots::raised_rounded[12]:(94143178827,0)
___________________________________
ct_roots::raised[13]:(94143178827.000259,-0.0011072707515136966)
ct_roots::raised_rounded[13]:(94143178827,0)
___________________________________
ct_roots::raised[14]:(94143178826.999603,-0.00046140166166721089)
ct_roots::raised_rounded[14]:(94143178827,0)
___________________________________
ct_roots::raised[15]:(94143178827.000259,0.00018446742817926839)
ct_roots::raised_rounded[15]:(94143178827,0)
___________________________________
ct_roots::raised[16]:(94143178827.000259,-0.00050751851871203122)
ct_roots::raised_rounded[16]:(94143178827,0)
___________________________________
ct_roots::raised[17]:(94143178827.000259,-0.0005305769472344397)
ct_roots::raised_rounded[17]:(94143178827,0)
___________________________________
ct_roots::raised[18]:(94143178827.000259,-0.00088809913494129387)
ct_roots::raised_rounded[18]:(94143178827,0)
___________________________________
ct_roots::raised[19]:(94143178827.000259,-0.0012456213226481479)
ct_roots::raised_rounded[19]:(94143178827,0)
___________________________________
ct_roots::raised[20]:(94143178827.000259,-0.0012686797511705563)
ct_roots::raised_rounded[20]:(94143178827,0)
___________________________________
ct_roots::raised[21]:(94143178827.000259,4.6116857044817097e-05)
ct_roots::raised_rounded[21]:(94143178827,0)
___________________________________
ct_roots::raised[22]:(94143178827.000259,-0.00031140533066203698)
ct_roots::raised_rounded[22]:(94143178827,0)
___________________________________
 
 
avg_err:0.00056815732700208645
___________________________________
root[0]:(3,0) - 3
root[1]:(2.8887518620433976,0.80939031347107282) - 2.9999999999999996
root[2]:(2.5632582136394655,1.5587518501063007) - 3
root[3]:(2.0476594296559623,2.1925078928343722) - 3
root[4]:(1.3801951131934567,2.6636556552071258) - 3
root[5]:(0.61036803915790194,2.9372522630469682) - 2.9999999999999996
root[6]:(-0.20472724009401264,2.9930063075716173) - 2.9999999999999996
root[7]:(-1.0046388365129584,2.8267827663564615) - 3
root[8]:(-1.7300409663446012,2.4509096790313265) - 3
root[9]:(-2.3271338721132588,1.893263832978159) - 3
root[10]:(-2.7516339045163587,1.1952032695387254) - 3
root[11]:(-2.9720578381089924,0.40849994728873995) - 3
root[12]:(-2.9720578381089924,-0.40849994728873917) - 3
root[13]:(-2.7516339045163596,-1.1952032695387236) - 3
root[14]:(-2.3271338721132593,-1.8932638329781581) - 2.9999999999999996
root[15]:(-1.7300409663446015,-2.4509096790313261) - 3
root[16]:(-1.0046388365129593,-2.8267827663564611) - 3
root[17]:(-0.20472724009401405,-2.9930063075716173) - 3
root[18]:(0.61036803915789994,-2.9372522630469691) - 3
root[19]:(1.3801951131934547,-2.6636556552071267) - 3
root[20]:(2.0476594296559609,-2.1925078928343735) - 3
root[21]:(2.5632582136394655,-1.5587518501063007) - 3
root[22]:(2.8887518620433976,-0.80939031347107315) - 3
___________________________________
 
 
Fin, hit <ENTER> to exit...
 
 
The shows all of the roots. Yours only shows the primary root.
 
Please correct me if I am totally wrong.
 
;^o
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 11 01:39PM -0700

On 4/10/2017 10:41 PM, Christian Gollwitzer wrote:
>> ct_float radius = std::pow(std::abs(z), 1.0 / p);
>> ct_float angle_base = std::arg(z) / p;
>> ct_float angle_step = (CT_PI * 2.0) / p;
[..]
> myroots.push_back(baseroot);
 
> ct_complex root = baseroot;
> ct_complex phasor = baseroot / std::abs(baseroot);
 
Afaict, phasor will always be 1+0i.
 
 
Christian Gollwitzer <auriocus@gmx.de>: Apr 11 10:45PM +0200

Am 11.04.17 um 21:13 schrieb Chris M. Thomasson:
> [...]
 
> The shows all of the roots. Yours only shows the primary root.
 
> Please correct me if I am totally wrong.
 
puh. this endless listing of code and results makes it hard to find the
bug. The problem is that the phasor is wrong; it is not z/|z| as I
posted (a "unit" complex pointing to z) but a unit complex with the
angle 2*pi/n.
Try:
 
const ct_complex i = ct_complex(0,1);
ct_complex phasor = std::exp(2 * i * M_PI / p);
 
(untested, again).
 
Sorry for the mistake.
 
Christian
Christian Gollwitzer <auriocus@gmx.de>: Apr 11 10:58PM +0200

Am 11.04.17 um 22:39 schrieb Chris M. Thomasson:
>> ct_complex root = baseroot;
>> ct_complex phasor = baseroot / std::abs(baseroot);
 
> Afaict, phasor will always be 1+0i.
 
For positive real input, yes - try a complex number like 1+2i to see
what it gives. Of course, the correct solution is a different number.
 
Christian
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 11 02:00PM -0700

On 4/11/2017 1:45 PM, Christian Gollwitzer wrote:
 
>> Please correct me if I am totally wrong.
 
> puh. this endless listing of code and results makes it hard to find the
> bug.
 
sorry about that.
 
 
> const ct_complex i = ct_complex(0,1);
> ct_complex phasor = std::exp(2 * i * M_PI / p);
 
> (untested, again).
 
Works like a charm. Thank you Christian. :^)
 
As you mentioned, the average error is greater at:
 
cg_roots = avg_err:0.0010976249994551542
 
vs. the slow trig original:
 
ct_roots = avg_err:0.00056815732700208645
 
but it works fine. Thanks again.
 
 
> Sorry for the mistake.
 
No problem at all! :^)
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 11 02:15PM -0700

On 4/11/2017 1:58 PM, Christian Gollwitzer wrote:
 
>> Afaict, phasor will always be 1+0i.
 
> For positive real input, yes - try a complex number like 1+2i to see
> what it gives. Of course, the correct solution is a different number.
 
Doh! Of course you are correct here. Sorry.
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 11 02:20PM -0700

On 4/11/2017 11:54 AM, Stefan Ram wrote:
> generator of rotations around the z axis. (The following
> pages then explain how finite rotations can be obtained
> from such "infinitesimal rotations".)
 
Nice.
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 11 02:25PM -0700

On 4/10/2017 11:23 PM, Alf P. Steinbach wrote:
> and so on. But what /causes/ this behavior eludes me. And even though
> I'm old and pretty stupid now, I have been good at math, and I believe
> I've been thinking about this also in my younger days.
[...]
 
Once one converts a complex number z to polar form, raising to a power
becomes clear to me. Christian's use of raising e to the power of
 
2.0 * i * CT_PI / (ct_float)p
 
_________________
const ct_complex i = ct_complex(0, 1);
ct_complex phasor = std::exp(2.0 * i * CT_PI / (ct_float)p);
_________________
 
is right on par! ;^)
 
A little less accurate, but much much faster!
ram@zedat.fu-berlin.de (Stefan Ram): Apr 11 06:54PM

>I still don't understand how rotation, and thereby the structure
>(metric) of our physical environment, emerges in complex arithmetic.
 
The numbers 1 and i also can be represented as 2×2 matrices
 
 
/ \
| 1 0 |
1 = | |
| 0 1 |
\ /
 
and
 
 
/ \
| 0 -1 |
i = | | .
| 1 0 |
\ /
 
 
See Wikipedia »7.2 Matrix representation of complex
numbers«.
 
Now, compare this with the matrix M_z on page 2 "259" in
 
www.astro.caltech.edu/~golwala/ph125ab/ph106ab_notes_sec5.1.pdf
 
. We can thus see that this matrix is the infinitesimal
generator of rotations around the z axis. (The following
pages then explain how finite rotations can be obtained
from such "infinitesimal rotations".)
bitrex <bitrex@de.lete.earthlink.net>: Apr 11 11:58AM -0400

Suppose I have a class such as:
 
class Foo
{
public:
Foo(std::stack<Bar>& ref1, Baz *const ref2) :
_ref1(ref1), _ref2(ref2)
{}
 
// etc.
 
private:
std::stack<Bar>& _ref1;
Baz *const _ref2;
};
 
The standard says (for C++11):
 
"A defaulted copy assignment operator for class T is defined as deleted
if any of the following is true:
 
T has a non-static data member of non-class type (or array thereof) that
is const;
 
T has a non-static data member of a reference type;
 
T has a non-static data member or a direct or virtual base class that
cannot be copy-assigned (overload resolution for the copy assignment
fails, or selects a deleted or inaccessible function);
 
T is a union-like class, and has a variant member whose corresponding
assignment operator is non-trivial."
 
It also says:
 
"The copy assignment operator for class T is trivial if all of the
following is true:
 
it is not user-provided (meaning, it is implicitly-defined or
defaulted), , and if it is defaulted, its signature is the same as
implicitly-defined (until C++14);
 
T has no virtual member functions;
 
T has no virtual base classes;
 
the copy assignment operator selected for every direct base of T is trivial;
 
the copy assignment operator selected for every non-static class type
(or array of class type) member of T is trivial.
 
A trivial copy assignment operator makes a copy of the object
representation as if by std::memmove. All data types compatible with the
C language (POD types) are trivially copy-assignable."
 
 
 
Which of these situations takes precedence for a class like my example?
It does contain a reference, yet given that it has no other fields other
than what are essentially pointers which aren't allowed to change, a
std::memmove should work fine for copying it.
red floyd <dont.bother@its.invalid>: Apr 11 09:28AM -0700

On 4/11/2017 8:58 AM, bitrex wrote:
> if any of the following is true:
 
> T has a non-static data member of non-class type (or array thereof) that
> is const;
 
[redacted]
 
I'm no language guru, but it seems to me that _ref2 is a non-static data
member of non-class type that is const.
Bonita Montero <Bonita.Montero@gmail.com>: Apr 11 08:08PM +0200

> std::memmove should work fine for copying it.
 
LOL!
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 11 08:27PM +0200

On 11-Apr-17 5:58 PM, bitrex wrote:
 
> Which of these situations takes precedence for a class like my example?
> It does contain a reference, yet given that it has no other fields other
> than what are essentially pointers which aren't allowed to change, a
 
[c:\Temp]
> type foo.cpp
#include <stdio.h>
 
struct X
{
int& ref;
};
 
auto main()
-> int
{
int gosh = 42;
X a{ gosh }, b{ gosh };
a = b;
}
 
[c:\Temp]
> g++ foo.cpp
foo.cpp: In function 'int main()':
foo.cpp:13:9: error: use of deleted function 'X& X::operator=(const X&)'
a = b;
^
foo.cpp:3:8: note: 'X& X::operator=(const X&)' is implicitly deleted
because the default definition would be ill-formed:
struct X
^
foo.cpp:3:8: error: non-static reference member 'int& X::ref', can't use
default assignment operator
 
[c:\Temp]
> _
 
 
> std::memmove should work fine for copying it.
 
Lols. :)
 
 
Cheers & hth.,
 
- Alf
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: