Getter using references and returning a constant variable - constants

I have the following question: I define a class containing a private vector of (my) objects - i.e.:
vector<myOtherClass> myVector;
Then I would like to define a getter method which should not copy all objects saved in the vector. Thus I am always using references:
vector<myOtherClass> &getMyVector() const {
return (myVector);
}
The “const” means that I can only read the member variables in this method. But what should I do if I want that the returning variable is a constant - in particular what difference is between the three following possibilities (sometimes, the compiler allows me only to use one of them):
const vector<myOtherClass> &getMyVector() const {
return (myVector);
}
,
vector<myOtherClass> const &getMyVector() const {
return (myVector);
}
and
const vector<myOtherClass> const &getMyVector() const {
return (myVector);
}

Related

Case expressions must be constant in Dart [duplicate]

Let's say I have a ColorPalette class that looks like the following:
class ColorPalette {
static const Map<int, Color> gray = {
400: Color(0xFFDDDDDD),
500: Color(0xFFEEEEEE),
// ...
};
// Primary colors in separate variable
static const Color primaryBlue = Color(0xFF0000FF);
// ...
}
And if I were to assign a color value of the map to a variable that expects a const value:
class SomeOtherClass {
static const Map<String, Color> stateColor = {
// Error
'pressed': ColorPalette.gray[500],
}
}
Complains that "Const variables must be initialized with a constant value."
But this works fine:
...
'pressed': ColorPalette.primaryBlue,
...
Plus when assigning map, doing 500: const Color(...) or static const Map<int, Color> gray = const {...} didn't work either.
So I suspect that this is throwing error probably because compiler doesn't evaluate all entries in the map during compile time and therefore, the value being accessed with the given key can be only known during runtime?
Is there any workaround to assign value from a map to a variable that expects a const value?
There is no workaround.
An expression of the form e1[e2] cannot be a constant. The [] operator is a method (all user-definable operators are), and you cannot call a method at compile time except for a very small number of operations on known system types. Map lookup, even on constant maps, is not one of those exceptions.
The reason ColorPalette.primaryBlue works is that it directly references a const variable.

Dart / Flutter nested classes static access

I'm trying to use a version of nested classes to make a tree of constant strings throughout my app in Flutter. I'd like them to be nested in order to find const strings quickly as the app grows, but still have the additional 'speed' of using the const keyword for Text() widgets.
However, I'm having a hard time trying to use them in const Text() widgets.
Here's a sample:
class Strings {
static const String ok = 'OK';
static TechnicianStrings technicianStrings = TechnicianStrings();
}
class TechnicianStrings {
TechnicianStrings();
final String createTech = 'Create Technician';
final String technician = 'Technician';
}
Throughout the app, I'd like to use these constant Strings as so:
const Text(Strings.ok), // <-- this works
const Text(Strings.technicianStrings.technician), //<-- only works without 'const'
const Text(Strings.technicianStrings.createTech), //<-- only works without 'const'
However, I get an error of "Arguments of a constant creation must be constant expressions" when I use the const keyword for the text widgets.
I've tried to use varying "const and static" names for the members of TechnicianStrings, and I get errors such as "invalid Constant" for the text widget. I also defined TechnicianStrings as static const, and got an error of 'Constant variables must be initialized with a constant value' for the line:
static const TechnicianStrings technicianStrings = TechnicianStrings();
Is there a way to use such a nested class structure hand in hand with const Text() widgets?
You need a constant constructor in TechnicianStrings.
class Strings {
static const String ok = 'OK';
static const TechnicianStrings technicianStrings = TechnicianStrings();
}
class TechnicianStrings {
const TechnicianStrings(); // <---
final String createTech = 'Create Technician';
final String technician = 'Technician';
}

Difference between static and const variable in Dart

Check these two examples:
static const inside of class:
class SessionStorage {
static const String _keySessionExist = 'storage.key';
}
Just a const outside of the class:
const String _keySessionExist = 'storage.key';
class SessionStorage {
}
Is there any difference or implications between having a static const variable inside of a class or just having it declared as const outside of it in Dart?
Maybe the compiled code changes?
Which one is more performant?
Which one should we follow if the variable is private to the file?
The declaration for cons must be using const. You have to declare it as static const rather than just const.
static, final, and const mean entirely distinct things in Dart:
static means a member is available on the class itself instead of on instances of the class. That's all it means, and it isn't used for anything else. static modifies members.
final means single-assignment: a final variable or field must have an initializer. Once assigned a value, a final variable's value cannot be changed. final modifies variables.
const has a meaning that's a bit more complex and subtle in Dart. const modifies values. You can use it when creating collections, like const [1, 2, 3], and when constructing objects (instead of new) like const Point(2, 3). Here, const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.
Const objects have a couple of interesting properties and restrictions:
They must be created from data that can be calculated at compile time. A const object does not have access to anything you would need to calculate at runtime. 1 + 2 is a valid const expression, but new DateTime.now() is not.
They are deeply, transitively immutable. If you have a final field containing a collection, that collection can still be mutable. If you have a const collection, everything in it must also be const, recursively.
They are canonicalized. This is sort of like string interning: for any given const value, a single const object will be created and re-used no matter how many times the const expression(s) are evaluated. In other words:
getConst() => const [1, 2];
main() {
var a = getConst();
var b = getConst();
print(a === b); // true
}
I think Dart does a pretty good job of keeping the semantics and the keywords nicely clear and distinct. (There was a time where const was used both for const and final. It was confusing.) The only downside is that when you want to indicate a member that is single-assignment and on the class itself, you have to use both keywords: static final.
Also:
I suggest you to have a look at this question
What is the difference between the "const" and "final" keywords in Dart?
Is there any difference or implications between having a static const variable inside of a class or just having it declared as const outside of it in Dart?
The obvious difference is that the static version must be referenced with the class name. Other than the change in name resolution, the should be the same.
Maybe the compiled code changes?
Which one is more performant?
They're both compile-time constants. There shouldn't be any difference.
Which one should we follow if the variable is private to the file?
If you want something that's private to a Dart library (which usually means the file), then prefix it with _. It doesn't matter whether it's global or static.

In dart, how to assign a value from a const Map to a const variable?

Let's say I have a ColorPalette class that looks like the following:
class ColorPalette {
static const Map<int, Color> gray = {
400: Color(0xFFDDDDDD),
500: Color(0xFFEEEEEE),
// ...
};
// Primary colors in separate variable
static const Color primaryBlue = Color(0xFF0000FF);
// ...
}
And if I were to assign a color value of the map to a variable that expects a const value:
class SomeOtherClass {
static const Map<String, Color> stateColor = {
// Error
'pressed': ColorPalette.gray[500],
}
}
Complains that "Const variables must be initialized with a constant value."
But this works fine:
...
'pressed': ColorPalette.primaryBlue,
...
Plus when assigning map, doing 500: const Color(...) or static const Map<int, Color> gray = const {...} didn't work either.
So I suspect that this is throwing error probably because compiler doesn't evaluate all entries in the map during compile time and therefore, the value being accessed with the given key can be only known during runtime?
Is there any workaround to assign value from a map to a variable that expects a const value?
There is no workaround.
An expression of the form e1[e2] cannot be a constant. The [] operator is a method (all user-definable operators are), and you cannot call a method at compile time except for a very small number of operations on known system types. Map lookup, even on constant maps, is not one of those exceptions.
The reason ColorPalette.primaryBlue works is that it directly references a const variable.

Invalid initialization of reference type 'Class&' from expression of type 'Class'

Ok guys , so I have a list of objects and I want to sort my list by a boolean function I created .
Function ->
bool funct(Student &s1,Student &s2)
{
return s1.calculMedie()<s2.calculMedie();
}
I got this list:
list<Student*> list;
list.push_back(sx[0]);
list.push_back(sx[1]);
list.push_back(sx[2]);
sx is comming from this declaration-> Student **sx=new Student*[3];
I created 3 objects of the type class Student.
I want to sort them by 'calculMedie()' which is a function that returns their average grade.
double Student::calculMedie()
{
int nr=0;
double s=0;
for(auto i : note)
{
nr++;
s=s+i;
}
return s/nr;}
^ thats how it looks.
And when I tried to do a list.sort(list.begin(),list.end(),funct) it gets me this error : " Invalid initialization of reference type 'Class&' from expression of type 'Class'"
It looks like you mixed std::sort algorithm with list<T>::sort method. List can be sorted only by using its sort method.
There are two overloads of list::sort:
void sort();
template< class Compare >
void sort( Compare comp ); // [2]
if you want to sort by comparator, write as follows:
list<Student*> list;
list.sort (funct);
because list stores pointers to Student, you need to modify signature of funct function, it must takes pointers not references:
bool funct(Student* s1,Student* s2)
{
return s1->calculMedie()<s2->calculMedie();
}
good practice is to pass s1,s2 as pointers to const object, when you change s1,s2 to be const Student* s1, const Student* s2 you need also to make calculMedie as const member function.