What is const & method in C++ - class

I saw code like that.
What this & means and what is the official name of this kind of methods?
struct S{
int get() const &{
return 5;
}
};
int main(){
S s;
return s.get();
}

The const & on the method signature means that the calling object shall be bounded to a const lvalue reference.
However, since rvalue can be bound to a const lvalue ref, the following code would compile:
struct S{
int get() const &{
return 5;
}
};
int main(){
return S{}.get(); // compiles, S{} can be bound to const lvalue
}
To see the actual meaning of the & you can either add a version for && or drop the const:
With an overload for const &&:
struct S{
int get() const &{
return 5;
}
int get() const && {
return -5;
}
};
int main(){
return S{}.get(); // returns -5
}
With & but without const:
struct S{
int get() & {
return 5;
}
};
int main(){
return S{}.get(); // compilation error cannot bind rvalue to lvalue
}

The const means the function itself is const - it is a compile time error for that function to modify the member data items of the class/struct, and therefore the function can be called using a const reference to an instance of the class.
The trailing & is very unusual (I've never seen one in the wild). It means the reference to the instance that is used to invoke this function must be an lvalue. A function followed by && must be called from an rvalue.
I believe a function can be declared and defined twice, once with & and once with &&, as it forms part of the signature. This is useful for certain obscure optimizations (apparently).

Related

How structs are extended just importing packages in D?

I have this fibonacci number generator.
struct FibonacciSeries
{
int first = 0;
int second = 1;
enum empty = false;
#property int front() const
{
return first;
}
void popFront()
{
int third = first + second;
first = second;
second = third;
}
#property FibonacciSeries save() const
{
return this;
}
}
This struct does not have the take method, so I have this error when executing this command (writeln(FibonacciSeries().take(5))).
a.d(66): Error: no property 'take' for type 'FibonacciSeries'
However, by importing range package, it has the take method. What's the mechanism behind this?
The mechanism is Uniform Function Call Syntax:
http://dlang.org/function.html#pseudo-member
To put it simply, if a.foo(b...) is not valid, the compiler tries rewriting it to foo(a, b...).

mutable method X.this is not callable using a immutable object error in D

I have this D code copied from this page: http://ddili.org/ders/d.en/class.html
import std.stdio;
struct S {
this (int x) {
this.x = x;
}
int x;
}
class Foo
{
S o;
char[] s;
int i;
// ...
this(S o, const char[] s, int i)
{
this.o = o;
this.s = s.dup;
this.i = i;
}
Foo dup() const
{
return new Foo(o, s, i);
}
immutable(Foo) idup() const
{
return new immutable(Foo)(this.o, this.s, this.i);
}
}
void main()
{
auto var1 = new Foo(S(5), "hello", 42);
auto var2 = var1.dup();
immutable(Foo) imm = var1.idup();
writeln(var1);
writeln(var2);
writeln(imm);
}
The issue is that I have "mutable method a.Foo.this is not callable using a immutable object" error when compile it.
You're receiving this error because you called new immutable(Foo)(this.o, this.s, this.i); This looks for a an immutable constructor, and you only have a constructor for a mutable object defined, which is the default. You can solve this by writing a constructor and marking it immutable, much like how you mark methods as const, but there is better and often easier solution.
Try marking your constructors and methods as pure if you can. If you mark the constructor as pure, then the constructor can be used for both mutable and immutable objects. Alternatively, you can mark your idup method as pure, construct a new Foo, which is a mutable object, and return it as immutable. This is all because pure functions can safely create immutable data if the data returned isn't referenced elsewhere. In other words, uniquely owned memory can be moved out into immutable types.

A program using class template, pair, vector

I'm trying to program the following:
A template class map having a pointer to a vector that contains elements std::pair<T,Q>, where T and Q are template types. It's supposed to work similarly to std::map and T is 'key' type, whereas Q stands for 'value' type. Besides the following should be implemented:
1. Constructor & destructor.
2. Function empty returning bool (if the object is empty).
3. Function size (using count_if)
4. Function clear that deletes all vector records.
5. Operator [] which allows for: map["PI_value"] = 3.14; It should use function find
6. Operators =, ==, !=, >> (using equal function)
I've been trying to code the above task, but have stuck on the code below.
Do you have any ideas to repair this mess?
#include <iostream>
#include <tuple>
#include <utility>
#include <algorithm>
#include <vector>
using namespace std;
template <typename T, typename Q>
class mapa
{
private:
vector<std::pair<T,Q>>* ptr;
public:
/**< DEFAULT CONSTRUCTOR/////////////////////////// */
mapa()
{
ptr = new vector<std::pair<T,Q>>;
ptr->push_back(std::pair<T,Q>(0,0));
}
/**< DESTRUCTOR////////////////////////////////////// */
~mapa(){ delete ptr;}
/**< EMPTY()////////////////////////////// */
bool empty()
{
if(ptr)
return false;
else
return true;
}
/**< SIZE()///////////////////////////////// */
int size()
{
return ptr->size();
}
/**< CLEAR()///////////////////////////////// */
void clear()
{
ptr->clear(ptr->begin(), ptr->end());
}
/**< OPERATOR[]/////////////////////////////////////////// */
vector<std::pair<T,Q>>* & operator[](T key)
{
auto ptr2 = ptr;
if(empty())
{
std::pair<T,Q> para;
para.first = key;
para.second = 0;
ptr2->push_back(para);
//ptr2->push_back(std::pair<T,Q>(key,0));
}
else
{
auto ptr2 = find_if( ptr->begin(), ptr->end(),
[](std::pair<T,Q> example,T key)
{
return(example.first==key);
}
);
}
return ptr2;
}
}; //class end
The lambda provided to std::find_if is declared wrong.
If you see e.g. this reference for std::find_if, you will see that the functions should be like
bool pred(const Type &a)
That means the lambda should be something like
[&key](const std:pair<T, Q>& element) { return element.first == key }
There are also other problems with your operator[] function, like that it should return Q& instead of a reference to the vector pointer. You should also remember that std::find_if returns an iterator to the found element, or end() if not found.

What are function typedefs / function-type aliases in Dart?

I have read the description, and I understand that it is a function-type alias.
A typedef, or function-type alias, gives a function type a name that you can use when declaring fields and return types. A typedef retains type information when a function type is assigned to a variable.
http://www.dartlang.org/docs/spec/latest/dart-language-specification.html#kix.yyd520hand9j
But how do I use it? Why declaring fields with a function-type? When do I use it? What problem does it solve?
I think I need one or two real code examples.
A common usage pattern of typedef in Dart is defining a callback interface. For example:
typedef void LoggerOutputFunction(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Running the above sample yields the following output:
Hello World
2012-09-22 10:19:15.139: Hello World
The typedef line says that LoggerOutputFunction takes a String parameter and returns void.
timestampLoggerOutputFunction matches that definition and thus can be assigned to the out field.
Let me know if you need another example.
Dart 1.24 introduces a new typedef syntax to also support generic functions. The previous syntax is still supported.
typedef F = List<T> Function<T>(T);
For more details see https://github.com/dart-lang/sdk/blob/master/docs/language/informal/generic-function-type-alias.md
Function types can also be specified inline
void foo<T, S>(T Function(int, S) aFunction) {...}
See also https://www.dartlang.org/guides/language/language-tour#typedefs
typedef LoggerOutputFunction = void Function(String msg);
this looks much more clear than previous version
Just slightly modified answer, according to the latest typedef syntax, The example could be updated to:
typedef LoggerOutputFunction = void Function(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Typedef in Dart is used to create a user-defined function (alias) for other application functions,
Syntax: typedef function_name (parameters);
With the help of a typedef, we can also assign a variable to a function.
Syntax:typedef variable_name = function_name;
After assigning the variable, if we have to invoke it then we go as:
Syntax: variable_name(parameters);
Example:
// Defining alias name
typedef MainFunction(int a, int b);
functionOne(int a, int b) {
print("This is FunctionOne");
print("$a and $b are lucky numbers !!");
}
functionTwo(int a, int b) {
print("This is FunctionTwo");
print("$a + $b is equal to ${a + b}.");
}
// Main Function
void main() {
// use alias
MainFunction number = functionOne;
number(1, 2);
number = functionTwo;
// Calling number
number(3, 4);
}
Output:
This is FunctionOne
1 and 2 are lucky numbers !!
This is FunctionTwo
3 + 4 is equal to 7
Since dart version 2.13 you can use typedef not only with functions but with every object you want.
Eg this code is now perfectly valid:
typedef IntList = List<int>;
IntList il = [1, 2, 3];
For more details see updated info:
https://dart.dev/guides/language/language-tour#typedefs
https://www.tutorialspoint.com/dart_programming/dart_programming_typedef.htm
typedef ManyOperation(int firstNo , int secondNo); //function signature
Add(int firstNo,int second){
print("Add result is ${firstNo+second}");
}
Subtract(int firstNo,int second){
print("Subtract result is ${firstNo-second}");
}
Divide(int firstNo,int second){
print("Divide result is ${firstNo/second}");
}
Calculator(int a,int b ,ManyOperation oper){
print("Inside calculator");
oper(a,b);
}
main(){
Calculator(5,5,Add);
Calculator(5,5,Subtract);
Calculator(5,5,Divide);
}

Question about var type

I am new to C# 3.0 var type. Here I have a question about this type. Take the following simple codes in a library as example:
public class MyClass {
public var Fn(var inValue)
{
if ( inValue < 0 )
{
return 1.0;
}
else
{
return inValue;
}
}
}
I think the parameter is an anonymous type. If I pass in a float value, then the Fn should return a float type. If a double value type is passed in, will the Fn return a double type? How about an integer value type as input value?
Actually, I would like to use var type with this function/method to get different return types with various input types dynamically. I am not sure if this usage is correct or not?
You can't use var for return values or parameter types (or fields). You can only use it for local variables.
Eric Lippert has a blog post about why you can't use it for fields. I'm not sure if there's a similar one for return values and parameter types. Parameter types certainly doesn't make much sense - where could the compiler infer the type from? Just what methods you try to call on the parameters? (Actually that's pretty much what F# does, but C# is more conservative.)
Don't forget that var is strictly static typing - it's just a way of getting the compiler to infer the static type for you. It's still just a single type, exactly as if you'd typed the name into the code. (Except of course with anonymous types you can't do that, which is one motivation for the feature.)
EDIT: For more details on var, you can download chapter 8 of C# in Depth for free at Manning's site - this includes the section on var. Obviously I hope you'll then want to buy the book, but there's no pressure :)
EDIT: To address your actual aim, you can very nearly implement all of this with a generic method:
public class MyClass
{
public T Fn<T>(T inValue) where T : struct
{
Comparer<T> comparer = Comparer<T>.Default;
T zero = default(T);
if (comparer.Compare(inValue, zero) < 0)
{
// This is the tricky bit.
return 1.0;
}
else
{
return inValue;
}
}
}
As shown in the listing, the tricky bit is working out what "1" means for an arbitrary type. You could hard code a set of values, but it's a bit ugly:
public class MyClass
{
private static readonly Dictionary<Type, object> OneValues
= new Dictionary<Type, object>
{
{ typeof(int), 1 },
{ typeof(long), 1L },
{ typeof(double), 1.0d },
{ typeof(float), 1.0f },
{ typeof(decimal), 1m },
};
public static T Fn<T>(T inValue) where T : struct
{
Comparer<T> comparer = Comparer<T>.Default;
T zero = default(T);
if (comparer.Compare(inValue, zero) < 0)
{
object one;
if (!OneValues.TryGetValue(typeof(T), out one))
{
// Not sure of the best exception to use here
throw new ArgumentException
("Unable to find appropriate 'one' value");
}
return (T) one;
}
else
{
return inValue;
}
}
}
Icky - but it'll work. Then you can write:
double x = MyClass.Fn(3.5d);
float y = MyClass.Fn(3.5f);
int z = MyClass.Fn(2);
etc
You cannot use var as a return type for a method.