CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   attempted to assign to a const reference to constant object of type (https://www.cfd-online.com/Forums/openfoam-programming-development/154477-attempted-assign-const-reference-constant-object-type.html)

gaza June 15, 2015 13:08

attempted to assign to a const reference to constant object of type
 
Hi Foamers,
I'm stuck and I need your help wuth error as in the title of this post.
My piece of code is

volScalarField A( T );
volScalarField B( T );
return Pair<tmp<volScalarField> >
(
A,
B
);

T is also volScalarField defined in the createFields.H

Can you tell me why "attempted to assign to a const reference to constant object of type" error arise? I find out that the error arises in
the constructor of Pair, but I don't understand why? Here is the code from Pair.H

//- Construct from components 66 inline Pair(const Type& f, const Type& s)
67 {
68 first() = f;
69 second() = s;
70 }

//- Return first 88 inline const Type& first() const
89 {
90 return this->operator[](0);
91 }
92
93 //- Return first
94 inline Type& first()
95 {
96 return this->operator[](0);
97 }
98
99 //- Return second
100 inline const Type& second() const
101 {
102 return this->operator[](1);
103 }
104
105 //- Return second
106 inline Type& second()
107 {
108 return this->operator[](1);
109 }

and operator[]() from FixedList.H

242 inline T& Foam::FixedList<T, Size>::operator[](const label i) 243 {
244 # ifdef FULLDEBUG
245 checkIndex(i);
246 # endif
247 return v_[i];
248 }
249
250
251 // const element access
252 template<class T, unsigned Size>
253 inline const T& Foam::FixedList<T, Size>::operator[](const label i) const
254 {
255 # ifdef FULLDEBUG
256 checkIndex(i);
257 # endif
258 return v_[i];
259 }

Any help is really appreciated

gaza June 16, 2015 04:41

Can anybody help me?

gaza June 16, 2015 10:51

Hi all,
I solved my problem by implementation:
volScalarField A( T );
volScalarField B( T );
return Pair<tmp<volScalarField> >
(
A*scalar(1),
B*scalar(1)
);

I do not know why now it works?
This solution is not good. If anybody know how to fix it please share your knowledge.
I don't think so it is a bug in tmp class. Rather I do something wrong. But why can't I
return Pair of volScalarField?? It is strange.

gaza June 17, 2015 02:53

This is strange for me that if I want return

Pair<tmp<volScalarField> >(A,B);

A and B have to be expressions. For example


Pair<tmp<volScalarField> >(A*scalar(1),B*scalar(1));

works and Pair<tmp<volScalarField> >(A,B); does not.

Does anybody know why it is?

anydimenx September 23, 2015 05:17

I meet the same problem.
 
I meet the same problem, my solution is :
Pair<tmp<volScalarField> >(1.0 * A, 1.0 * B);
It is like the solution above, but I don't know why. What if the type of A, B doesn't support the operator *? How to construct the object of type Pair?

gaza September 23, 2015 06:20

Hi anydimenx,
Yes I don't know what then.
But I think now I know the universal solution but I didn't check it.
Probably you have to use construction with "new" statement.
Something like that:

return Pair<tmp<volScalarField> >
(
new Pair<volScalarField>
(
A, B
)
);

but you have to check it because syntax could be wrong.

anydimenx September 24, 2015 10:13

The way to construct the object of Pair<T>
 
Hi, gaza, thank you for your ideas.
I have tried your solution, but it cannot pass the compiling. However, your idea enlightens me. It seems that I've found the universal solution:

return Pair<tmp<volScalarField> >
(
tmp<volScalarField>(A),
tmp<volScalarField>(B)
);

assuming A and B are objects of type volScalarField.

Pair<Type> is a class template, which has a constructor:

Pair(const Type& f, const Type& s)

So the arguments of that constructor should be of type tmp<volScalarField>

tmp<T> is a class template, which has a constructor:

tmp(const T&)

tmp<volScalarField>(A) creates an unnamed smart pointer of the instantiated class tmp<volScalarField>

And I search the declaration of operator* through the Doxygen:

tmp<GeometricField<Type, PatchField, GeoMesh> > Foam::operator*
(
const dimensioned<scalar>& dt1,
const GeometricField<Type, PatchField, GeoMesh>& df2
);

tmp<GeometricField<Type, PatchField, GeoMesh> > Foam::operator*
(
const GeometricField<Type, PatchField, GeoMesh>& df1
const dimensioned<scalar>& dt2,
)

tmp<GeometricField<Type, PatchField, GeoMesh> > Foam::operator*
(
const scalar& dt1,
const GeometricField<Type, PatchField, GeoMesh>& df2
);

tmp<GeometricField<Type, PatchField, GeoMesh> > Foam::operator*
(
const GeometricField<Type, PatchField, GeoMesh>& df1
const scalar& dt2,
);

So this is why A*scalar(1) and 1.0*A satisfy the type of the parameters of the class Pair constructor, but A cannot. The result of the multiplication is of type tmp<volScalarField>.

gaza September 24, 2015 10:37

Hi anydimenx,
Thank's a lot for your solution and explanation :)

anydimenx September 25, 2015 03:07

You are welcome, this discussion really helps me a lot, I enjoy it. Thank you for your inspiring and timely reply.

Best wishes.

gaza November 22, 2015 06:00

Quote:

Originally Posted by gaza (Post 550439)
Hi Foamers,
I'm stuck and I need your help wuth error as in the title of this post.
My piece of code is

volScalarField A( T );
volScalarField B( T );
return Pair<tmp<volScalarField> >
(
A,
B
);

T is also volScalarField defined in the createFields.H

Can you tell me why "attempted to assign to a const reference to constant object of type" error arise? I find out that the error arises in
the constructor of Pair, but I don't understand why? Here is the code from Pair.H

//- Construct from components 66 inline Pair(const Type& f, const Type& s)
67 {
68 first() = f;
69 second() = s;
70 }

//- Return first 88 inline const Type& first() const
89 {
90 return this->operator[](0);
91 }
92
93 //- Return first
94 inline Type& first()
95 {
96 return this->operator[](0);
97 }
98
99 //- Return second
100 inline const Type& second() const
101 {
102 return this->operator[](1);
103 }
104
105 //- Return second
106 inline Type& second()
107 {
108 return this->operator[](1);
109 }

and operator[]() from FixedList.H

242 inline T& Foam::FixedList<T, Size>::operator[](const label i) 243 {
244 # ifdef FULLDEBUG
245 checkIndex(i);
246 # endif
247 return v_[i];
248 }
249
250
251 // const element access
252 template<class T, unsigned Size>
253 inline const T& Foam::FixedList<T, Size>::operator[](const label i) const
254 {
255 # ifdef FULLDEBUG
256 checkIndex(i);
257 # endif
258 return v_[i];
259 }

Any help is really appreciated

this generally is solved in OF via such construction for instance (solver thermoFoam):

75 talphaEff = tmp<volScalarField>
76 (
77 new volScalarField
78 (
79 IOobject
80 (
81 "alphaEff",
82 runTime.timeName(),
83 mesh,
84 IOobject::NO_READ,
85 IOobject::NO_WRITE
86 ),
87 mesh,
88 dimensionedScalar("0", dimMass/dimLength/dimTime, 0.0)
89 )
90 );


All times are GMT -4. The time now is 19:48.