C++ same variable act as int and float - c++

I have on situation, where i need to keep the value float as well as int. so tried like below. but no help. can any one help on this?
union Val {
int a;
float b;
};
Val p;
p.b = 45.56;
int k = p.a; // i want k should be 45;

I see that you say:
i dont want each time it to be converted from float to int [sic]
To do that you could use user-defined conversions to accomplish this.
So your struct would look like this:
class Val {
int a;
float b;
public:
Val& operator= (const int _a) {a = _a; b = _a + fmod(b, 1.0F); return *this;}
Val& operator= (const float _b) {b = _b; a = trunc(_b); return *this;}
operator int() {return a;}
operator float() {return b;}
};
Please note that what you really want to use is simply a float with static_cast<int> For astatic_cast:
No checks are performed during runtime to guarantee that the object being converted is in fact a full object of the destination type. Therefore, it is up to the programmer to ensure that the conversion is safe. On the other side, it does not incur the overhead of the type-safety checks of dynamic_cast.
I've provided an example of using Val here: http://ideone.com/XUesib but you could accomplish the exact same thing given float foo like this:
foo = 1.3F;
cout << static_cast<int>(foo) << endl << foo << endl;
foo = 13 + fmod(foo, 1.0F);
cout << static_cast<int>(foo) << endl << foo << endl;

I have on situation, where i need to keep the value float as well as int. so tried like below
You can't do it with a union. A union can only hold a single value inside at any time. You need two separate variables. You can keep them in side a struct if you like:
struct Val {
int a;
float b;
};
Now you can have both an int and a float.
Val p;
p.b = 45.56;
p.a = p.b;
int k = p.a; // no conversion
That said, since you apparently only use a to store a converted value of b, you should measure whether the conversions even affect performance.

You can use structure with constructor, and initialize your variables in it as you wish.
struct Val {
int a;
float b;
Val(float value) {
a = b = value;
}
};
So you can use it in loop and don't worry about conversations each time, just create your Val variable outside loop and use it.

Related

Triangle , C++ construction, problem with calculating angles

I have a problem with my homework.
1) I should write the function SSS with inputs a, b and c. I need to output alpha, beta and gamma.
2) I should write the function SWS with inputs a, b, and gamma. And I need to output c, alpha and beta.
Here is my code:
#include <iostream>
#include <cmath>
#include <math.h>
#include <cstdio>
using namespace std;
double SSS_alpha(double a, double b, double c){
int bot1 = -2*b*c;
if(bot1==0.0){
return 0.0;
}
double alpha = acos((a*a-b*b-c*c)/bot1);
const double rad = 0.5729577951308232088;
return alpha*rad;
}
double SSS_beta(double a, double b, double c){
double bot2 = -2*c*a;
if(bot2==0.0){
return 0.0;
}
double beta = acos((b*b-c*c-a*a)/bot2);
const double rad = 0.5729577951308232088;
return beta*rad;
}
double SSS_gamma(double a, double b, double c){
double bot3 = -2*b*a;
if(bot3==0.0){
return 0.0;
}
double gamma = acos((c*c-a*a-b*b)/bot3);
const double rad = 0.5729577951308232088;
return gamma*rad;
}
double WSW_seite_c(double a, double b, double gamma){
double c_1 = (a*a+b*b-2*a*b*cos(gamma));
double c = sqrt(c_1);
return c;
}
int main(){
cout << SSS_alpha(5.0, 7.0, 8.0)<<endl;
cout <<SSS_beta(5.0, 7.0, 8.0)<<endl;
cout <<SSS_gamma(5,7,8)<<endl;
cout <<"Seite c: "<<WSW_seite_c(5, 7, 0.81)<<endl;
}
I can only return one argument in one function. And I have a lot of functions for task 1:for alpha, for beta, for gamma. And I don't know how I can write it in one function. I wrote only one function for finding c for task 2.
I am new to C++. I would be happy if you can help me.:)
Returning a struct or using a class Triangle as proposed are perfect solutions and it is what I generally use.
However, in some simple cases, returning more than one value through a tuple can be quite convenient.
I showed a simple "working" example below.
Note that I will generally avoid this kind of solution for more than 3 return objects, to avoid confusion.
#include <iostream>
#include <tuple>
std::tuple<double, double, double> f(double x, double y){
double a = x;
double b = x+y;
double c = x-y;
return std::make_tuple(a, b, c);
}
int main() {
double a, b, c;
std::tie (a, b, c) = f (1.0, 2.0);
std::cout << "a = " << a << "\n";
std::cout << "b = " << b << "\n";
std::cout << "c = " << c << "\n";
return 0;
}
I hope the code is self explaining.
The syntax can be simplified with C++17. I did not use these simplifications because my current compiler is not compatible!
This approach can be combined with the struct one, as one can return several structs through a tuple.
Edit: I just see that NathanOliver already mentioned the tuple possibility in a comment...
First you dont need cstdio if you include iostream which you should preferably do in C++ since cstdio is just the C library migrated to C++.
As for your problem it sounds like you need to pass the variables by value. Your favourite C++ Book should tell you that there are cases like yours, where you need to "return" more than one value. In that case you can pass pointers(C-Style) or the safer references to functions which kind of act like pointers.
So you actually would define your function as follows:
void SSS(double a, double b, double c, double & alpha, double & beta, double & gamma);
Or as stated by #Ripi2 pack the values in a struct and return a value of that type :
/* Thanks to NathanOliver in the comments */
struct Values {
double a;
double b;
double c;
};
Values SSS(double a, double b, double c) {
Values values;
/* Do stuff */
return values;
}
A struct will be the simplest way of doing what you want. You can also create a class, but it might be an overkill solution for a homework (they basically are the same, but see my comment thread to get my point of view on that matter).
a struct declaration goes like this :
struct containerName
{
int val_a;
double val_b;
//and so on : you put what ever you need
}
The struct then basically becomes a type you can use pretty much like int, double, bool etc.
Here's a nice reading on struct and how to use it
Yes, you can only return one object from a function. But you can have it return a compound object, like a struct or a class. Traditionally you use structs for data only objects, because that is what they were in C.
struct Triangle
{
double a;
double b;
double c;
};
Then you can return a Triangle object from a function. And access its members this way:
Triangle tri1; // first, create an instance of the struct
tri1.a = 5.0f; // assign a value to a member
It's good practice to choose meaningful names for your data types (just like with your variables) and always design the data types so that they represent what they are named.
To make the code more expressive you could take it further with a more object oriented approach. You could give the data type Triangle member functions which calculate its angles, so that you can "ask" the Triangle what its angles are.
(You should also name it a class at that point because it it is not a pure data structure anymore, but that is a matter of convention. in C++ structs and classes are almost the same.)
class Triangle
{
public:
// everything in this section can be accessed from outside
// this is a constructor. It is a special function that lets you create a Triangle
Triangle(double pa, double pb, double pc)
: a(pa), b(pb), c(pc) // initialize the members
{}
// getters for the private members (not needed but that way they can't directly be changed)
double get_a() const
{
return a;
}
double get_b() const
{
return b;
}
double get_c() const
{
return c;
}
double alpha() const;
double beta() const;
double gamma() const;
// should be const because they dont change anything about the object
private:
// the default access for classes, everything in this section can only be accessed by member functions
double a;
double b;
double c;
};
// member function definitions outside of class declaration
double Triangle::alpha() const
{
// calculate and return alpha...
}
double Triangle::beta() const
{
// calculate and return beta...
}
double Triangle::gamma() const
{
// ...
}
You can use this class this way:
int main()
{
// create a Triangle by calling the constructor
Triangle tri1(5.0, 7.0, 8.0);
std::cout << "Alpha: " << tri1.alpha() << std::endl;
std::cout << "Beta: " << tri1.beta() << std::endl;
std::cout << "Gamma: " << tri1.gamma() << std::endl;
return 0;
};

How to efficiently alias a float as both a named member and an element of an array?

I am implementing a particle-based fluid simulation. To represent vectors such as velocity, acceleration etc I have defined a class that looks like this
class Vec3f {
public:
float x, y, z;
// ... bunch of constructors, operators and utility functions
}
I'm using the library nanoflann for kd-tree searches. To accommodate for arbitrary class designs, nanoflann requires a user-defined adaptor class that the kd-tree class then queries to get info about the particle dataset. One function that the adaptor has to offer, as described in the nanoflann documentation is the following.
// Must return the dim'th component of the idx'th point in the class:
inline T kdtree_get_pt(const size_t idx, int dim) const { ... }
The problem is that this interface does not work seamlessly with the x, y, z representation. Naively, it would need to do something like this
inline float kdtree_get_pt(const size_t idx, int dim) const {
switch(dim) {
case 0:
return particlearray[idx].x;
case 1:
return particlearray[idx].y;
case 2:
return particlearray[idx].z;
}
}
Building and querying the kd-tree consumes a significant portion of my app's runtime and kd_tree_get_pt gets queried multiple times in the process so I need it to be optimized. The following solution should be faster.
class Vec3f {
public:
float values[3];
// ...
}
// Then inside the adaptor class
inline float kdtree_get_pt(const size_t idx, int dim) const {
return particlearrray[idx].values[dim];
}
However, I much prefer the x, y, z interface for my equations. Now that the problem is clear, my question is how can I keep the x, y, z notation for my equations without making kdtree_get_pt suboptimal.
Solutions I have considered:
Vec3f has member float values[3] and getters in the form of float& x(). The function call should be optimized away completely so this almost works but I do not want to have to add the parentheses in my equations if I can avoid it. eg I want to be able to write vec1.x - vec2.x instead of vec1.x() - vec2.x(). As far as I know, C++ does not offer a way to "disguise" a function call as a member variable, excluding preprocessor macros which I do not consider a safe solution.
Vec3f has members float values[3] and float& x, y, z where the latter are initialized to point to the corresponding floats in the array. I thought they would be optimized away as they are known at compile time and obviously cannot change value after initialization, but even with optimizations on, MSVC++ seems to actually store the float&s as can be seen by sizeof(Vec3f) growing by 12 bytes after their addition. This doubles the storage size of my dataset which raises a concern for cache misses when working with arbitrarily large datasets.
kdtree_get_pt uses float& values[3] to point to x, y, z. This might eliminate the branching cost, but I don't believe the extra level of indirection, nor the need to initialize all 3 references can be optimized away so it is presumably slower than the return particlearrray[idx][dim]` version.
kdtree_get_pt uses reinterpret_cast or pointer magic to directly point into Vec3f's members. Given a Vec3f object's address, I believe x, y, z are guaranteed to be stored in that order with the first one stored at the same address as the one given by the & operator on the Vec3f object, but even so I'm confused as to whether there exists a well-defined way to observe them.
From a software engineering standpoint, it's best to expose the data through accessor and modifier functions only.
I would suggest:
class Vec3f
{
public:
float& operator[](size_t index) { return values[index]; }
float operator[](size_t index) const { return values[index]; }
float& x() { return values[0]; }
float x() const { return values[0]; }
float& y() { return values[1]; }
float y() const { return values[1]; }
float& z() { return values[2]; }
float z() const { return values[2]; }
private:
float values[3];
}
Re: kdtree_get_pt uses reinterpret_cast or pointer magic to directly point into Vec3f's members.
That's a bad idea in general. However, I don't see that being a problem with my suggestion.
You should always check if the switch statements will really introduce branchings in the final compiled output. A tool that might help you there is godbolt.
For both of those code snippets (random and cout have been added to prevent complete removeal of the code):
#include<cstddef>
#include<array>
#include<iostream>
#include <ctime>
class Vec3f {
public:
float values[3];
};
struct Test {
std::array<Vec3f,100> particlearray;
float kdtree_get_pt(const size_t idx, int dim) const {
return particlearray[idx].values[dim];
}
};
int main() {
Test t;
std::srand(std::time(0));
int random_variable = std::rand();
std::cout << t.kdtree_get_pt(random_variable,0);
std::cout << t.kdtree_get_pt(random_variable,1);
std::cout << t.kdtree_get_pt(random_variable,2) << std::endl;
return 0;
}
and
#include<iostream>
#include<array>
#include<ctime>
#include<cstdlib>
#include<cstddef>
class Vec3f {
public:
float x, y, z;
};
struct Test {
std::array<Vec3f,100> particlearray;
float kdtree_get_pt(const size_t idx, int dim) const {
switch(dim) {
case 0:
return particlearray[idx].x;
case 1:
return particlearray[idx].y;
case 2:
return particlearray[idx].z;
}
}
};
int main() {
Test t;
std::srand(std::time(0));
int random_variable = std::rand();
std::cout << t.kdtree_get_pt(random_variable,0);
std::cout << t.kdtree_get_pt(random_variable,1);
std::cout << t.kdtree_get_pt(random_variable,2) << std::endl;
return 0;
}
The access to x, y and z or values[dim] will be compiled (by gcc 7) to:
cvtss2sd xmm0, DWORD PTR [rsp+rbx]
cvtss2sd xmm0, DWORD PTR [rsp+4+rbx]
cvtss2sd xmm0, DWORD PTR [rsp+8+rbx]
Without any branching.
There is known technique for mixing up access via x, y, z and array indices using union of identical data types. Resolves problem with UB, sizeof() is 12 bytes, access time is as fast as it can be, one could use SIMD vector in very similar fashion. Code below tested with VS2017
#include <iostream>
#include <type_traits>
template <int Size> struct VectorBase {
float _data[Size];
float operator[](int Index) {
return _data[Index];
}
};
template <typename VectorType, int Index> struct ScalarAccessor {
VectorType _v;
operator float() const {
return _v._data[Index];
}
float operator = (float x) {
_v._data[Index] = x;
return *this;
}
};
union uuu {
VectorBase<3> xyz;
ScalarAccessor<VectorBase<3>, 0> x;
ScalarAccessor<VectorBase<3>, 1> y;
ScalarAccessor<VectorBase<3>, 2> z;
};
template <int Size> struct Vector {
union
{
VectorBase<3> xyz;
ScalarAccessor<VectorBase<3>, 0> x;
ScalarAccessor<VectorBase<3>, 1> y;
ScalarAccessor<VectorBase<3>, 2> z;
};
float operator[](int Index) {
return xyz[Index];
}
};
using Vec3f = Vector<3>;
int main() {
Vec3f a;
a.x = 1.0f;
a.y = a.x + 3.0f;
a.z = a.x * 3.0f;
std::cout << sizeof(a) << "\n";
std::cout << a.x << " " << a.y << " " << a.z << "\n";
std::cout << a[0] << " " << a[1] << " " << a[2] << "\n";
std::cout << std::is_standard_layout<VectorBase<3>>::value << "\n";
std::cout << std::is_standard_layout<ScalarAccessor<VectorBase<3>, 0>>::value << "\n";
std::cout << std::is_standard_layout<ScalarAccessor<VectorBase<3>, 1>>::value << "\n";
std::cout << std::is_standard_layout<ScalarAccessor<VectorBase<3>, 2>>::value << "\n";
std::cout << std::is_standard_layout<Vec3f>::value << "\n";
std::cout << std::is_standard_layout<uuu>::value << "\n";
return 0;
}
UPDATE
Here some C++ standard reading
I'm relying on the definition of standard-layout type 12.7 Classes
A class S is a standard-layout class if it:
(7.1) — has no non-static data members of type non-standard-layout class (or array of such
types) or reference,
(7.2) — has no virtual functions (13.3) and no virtual base classes (13.1),
(7.3) — has the same access control (Clause 14) for all non-static data members,
(7.4) — has no non-standard-layout base classes, (7.5) — has at most one base class subobject of any given type
...
It is easy to check if all proposed classes are standard-layout - I've changed the code to check for that.
They are all layout-compatible, I believe
Also If a standard-layout class object has any non-static data members, its address is the same as the address of its first non-static data member.
Union is a standard-layout class as well, so we have classes aligned in union with only data member being array of the same type and size, and looks like standard requires it to be byte-by-byte compatible
However, I much prefer the x, y, z interface for my equations. Now that the problem is clear, my question is how can I keep the x, y, z
Declare x,y,z as local references before calculation:
auto& [x1, y1, z1] = v1.values;
auto& [x2, y2, z2] = v2.values;
return x1*x2 + y1*y2 + z1*z2;
For pre-C++17, you need more verbose:
auto& x = values[0];
auto& y = values[1];
auto& z = values[2];
The compiler will not need to use any storage for these references.
This of course introduces some repetition; One line (in C++17) per vector per function.
Extra parentheses introduced by your first suggestion is another good way to go. Whether the introduction of parentheses is better or worse than local reference declaration boiler plate depends on the use case and personal preference.
Edit: Another alternative: Define operator[] and use named constants for indices.
namespace axes {
enum axes {
x, y, z
};
}
struct Vec3f {
float values[3];
float& operator[](size_t index) { return values[index]; }
float operator[](size_t index) const { return values[index]; }
};
// usage
using namespace axes;
return v1[x]*v2[x] + v1[y]*v2[y] + v1[z]*v2[z];

C++ non-virtual class member variables memory layout?

I have a non-virtual class template A as below and I do the following
#include <iostream>
// my class template
template<typename T>
class A
{
public:
T x;
T y;
T z;
// bunch of other non-virtual member functions including constructors, etc
// and obviously no user-defined destructor
// ...
};
int main()
{
//now I do the following
A<double> a;
a.x = 1.0; // not important this
a.y = 2.0;
a.z = 3.0;
// now the concerned thing
double* ap = (double*)&a;
double* xp = &(a.x);
// can I correctly and meaningfully do the following?
double new_az = ap[2]; // guaranteed to be same as a.z (for any z) ? ** look here **
double new_z = xp[2]; // guaranteed to be same as a.z (for any z) ? ** look here **
std::cout<<new_az<<std::endl;
std::cout<<new_z<<std::endl;
return 0;
}
So, is it guaranteed that if I use a raw point to object A or to the member variable a.x, I will correctly get the other variables?
As many users pointed out, there is no guarantee that the memory layout of your structure will be identical to the appropriate array. And "ideologically correct" way to access members by index would be creating some ugly operator [] with a switch inside it.
However, speaking practically, there is usually no problem with your approach, and the suggested solutions are inferior in terms of code generated and run-time performance.
I can suggest 2 other solutions.
Keep your solution, but verify in compile-time that your structure layout corresponds to an array. In your specific case putting STATIC_ASSERT(sizeof(a) == sizeof(double)*3);
Change your template class to be actually an array, and convert the x,y,zvariables into the access functions into the elements of the array.
I mean:
#include <iostream>
// my class template
template<typename T>
class A
{
public:
T m_Array[3];
T& x() { return m_Array[0]; }
const T& x() const { return m_Array[0]; }
// repeat for y,z
// ...
};
If you make the length of the array (i.e. dimension of the represented vector) a template parameter as well, you may put a 'STATIC_ASSERT' in each access function to ensure the actual existence of the member.
No, there is no guarantee, not the way you do it. If T is a int8_t, for example, it would work only if you specified 1-byte packing.
The easiest, and correct way to do this, would be to add an operator [] to your template class, something like:
T& operator[](size_t i)
{
switch(i)
{
case 0: return x;
case 1: return y;
case 2: return z:
}
throw std::out_of_range(__FUNCTION__);
}
const T& operator[](size_t i) const
{
return (*const_cast<A*>(this))[i]; // not everyone likes to do this.
}
But this is not really efficient. A more efficient way is to have your vector (or point) coordinates in a array, and x(), y(), z() member functions to access them. Then you example would work in all cases, provided you implement a T* operator in your class.
operator T*() { return &values[0]; }
operator const T*()const { return &values[0]; }
If you really want to do such things:
template <typename T>
class FieldIteratable
{
using Data = std::array<T, 5/*magic number*/>;
Data data_;
public:
const Data & data() { return data_; }
T& a1 = data_[0]; // or some macro
char padding1[3]; // you can choose what field is iteratable
T& a2 = data_[1];
char padding2[3]; // class can contain other fields can be
T& a3 = data_[2];
char padding3[3];
T& a4 = data_[3];
char padding4[3];
T& a5 = data_[4];
};
int main() {
FieldIteratable<int> fi;
int* a = &fi.a1;
*a++ = 0;
*a++ = 1;
*a++ = 2;
*a++ = 3;
*a++ = 4;
std::cout << fi.a1 << std::endl;
std::cout << fi.a2 << std::endl;
std::cout << fi.a3 << std::endl;
std::cout << fi.a4 << std::endl;
std::cout << fi.a5 << std::endl;
for(auto i :fi.data())
std::cout << i << std::endl;
return 0;
}

Why does a const reference behave differently when assigned an l-value and r-value?

Given the code sample below;
#include<iostream>
using namespace std;
int main(){
int a = 4;
const int &b = a;
const int &c = a * 2;
a = 10;
cout << b << endl;
cout << c << endl;
return 0;
}
When I run this, the output is
10
8
Why is C++ designed to behave differently when assigning l-value and r-value to const references?
The expression:
const int &c = a * 2;
Does NOT bind the resulting reference c to a. Instead it binds it to the rvalue that is the result of the expression a * 2, which is a temporary object that no longer has anything to do with a - thus changing a does not affect it.
This is as opposed to b, which is a reference to the object a.
const int &b = a;
const int &c = a * 2;
The b here is a reference (an alias) for a; as a changes value, b will reflect that.
c binds to the temporary object as calculated by the expression a * 2, as a changes value after the computation, the calculation is not recomputed, the value of c remains as it was originally computed.
Other answers already explain why you get the output that you get. However, lets assume you want
const int &c = a * 2;
a = 10;
cout << c << endl;
to print 20. This is possible, but not by using a const ref directly, e.g. like this:
struct myref {
const int& x;
myref(int& x) : x(x) {}
operator int() { return x*2;}
};
int main() {
int a = 0;
myref c(a);
a = 10;
std::cout << c << std::endl;
}
However, I would strongly suggest you not to use this code and I just wanted to demonstrate that it is possible (I took the "this is too ambitious" in a comment as a challenge).
I guess with lambdas this can be done in a much more elegant way, unfortunately I am not so familar with them.

What's the difference between function that returns float and float&?

What's the difference in usage of function get1() and get2()?
struct x
{
float get1() const
{
float fx = 4;
fx += 1.5f;
return fx;
}
float& get2() const
{
float fx = 4;
fx += 1.5f;
return fx;
}
};
int main()
{
x t;
float x1 = t.get1();
float/*&*/ x2 = t.get2();
cout << x1 << endl;
cout << x2 << endl;
cin.get();
}
As i understand, get2() can only be const class member..
It's not clear for me completely. If someone can point me to a reference or just a short but complete solution, would be nice.
In your case, get2() invokes undefined behavior because you return a reference to a method-local that goes out of scope.
The difference is that returning float returns a float value, while float & returns a reference to a float. The reference can be used to alter the data of the referent; when returning by value you just get a copy.
It sounds like you are just confused about what references do, so here is the colloquial definition: a reference is another name for an object. That means that a reference requires the existence of its target to exist elsewhere, very similar to a (non-null) pointer.
Let me write a better example to illustrate the difference:
struct x
{
x() : data(0) { }
float get1() const
{
return data;
}
// Cannot be const now, because we can't return a non-const reference to what
// would be a const data member. (If this method were const then data would be a
// const float, and that cannot bind to float &.)
float & get2()
{
return data;
}
private:
float data;
};
Now we have two methods, one that returns data and one that returns a reference to it. The difference here is that with get2() you can actually change the value of x::data:
x an_x;
float a = an_x.get1(); // a is 0
a = 5; // a is 5, an_x.data is still 0
a = x.get1(); // a is 0 again, because an_x.data did not change
float & b = an_x.get2(); // b is 0
b = 5; // b is 5, and so is an_x.data!
a = x.get1(); // a is now 5, because an_x.data is 5
Notably, returning a reference makes the result of the expression an lvalue:
an_x.get1() = 5; // Compile-time error, because a float is not an lvalue.
an_x.get2() = 5; // Compiles, and sets an_x.data to 5.
This is a technique used by the standard library containers; vector<int> for example returns int & from its non-const operator[] overload, which is why some_vector[0] = 5; compiles and works as you would expect.
float fx = 4;
In your case fx is local variable. It will die once you come out of function. If you are returning float then you are making copy of value, so even fx die, no problem. But if you are returning float&, you are returning reference to died variable. Which is undefined behaviour.
Copying is costly operation. When you return reference, you are not making actual copy, but you are returning address of varaiable. You should return reference if your variable will alive after returning from function. But in your case, fx will die once you come out of function.
I simulated your case in below blocks of code, you can compare the output of two case for making clearly. Hope it help.
#include <iostream>
class A
{
public:
A()
{
std::cout << this << ": A()\n";
}
A(const A&)
{
std::cout << this << ": Copy constructor\n";
}
~A()
{
std::cout << this << ": ~A()\n";
}
};
struct x
{
A get1() const
{
A a;
return a;
}
A &get2() const
{
A a;
return a;
}
};
int main(int argc, char *argv[])
{
x t;
/*{
t.get1();
}*/
{
t.get2();
}
std::cin.get();
}