左と右、moveとforward
10601 ワード
左と右
左:
すなわち、等号の左側の値です.通常、等号を使用して値を割り当てる場合、左側は値を付けられたオブジェクトです.では、左の値は名前とメモリのある値であることは明らかです.例:
右:
つまり、等号の右側の値です.同様に、割り当てを使用する場合、等号の右側の値は通常、既知で決定された値です.すなわち、右の値は名前もメモリもない値であり、通常は一時的な量を指すことができます.例:
moveとforward
move:
move、下位実装は実際には1つのタイプの強転であり、それは1つの左値を右値に強転する.vectorでのpush_back関数の実装では,左値と右値に対して異なる記憶動作を行う必要がある.しかしながら、右値を格納する記号自体が左値であるため(例えば、上記の例では12が右値であるが、kを用いて格納する場合、kは左値である)、右値パラメータに対応する関数を直接呼び出すことができず、moveを用いて右値に強く回転する必要がある.
forward:
上記のコードは,2つのパラメータに直面する1つの機能を実現するために,C++では関数テンプレートで完全に最適化できる繰返し率の高い2セグメントコードを用いたことを見ることができる.forwardでは、パラメータが左か右かを自動的に認識できます.(意味:タイプの完全な転送)したがって、コードは次のように最適化できます.
左:
すなわち、等号の左側の値です.通常、等号を使用して値を割り当てる場合、左側は値を付けられたオブジェクトです.では、左の値は名前とメモリのある値であることは明らかです.例:
int main()
{
int a=1;
int b=2;
// a、b
return 0;
}
右:
つまり、等号の右側の値です.同様に、割り当てを使用する場合、等号の右側の値は通常、既知で決定された値です.すなわち、右の値は名前もメモリもない値であり、通常は一時的な量を指すことができます.例:
class MyString
{
public:
MyString():p(nullptr){};
~MyString()
{
delete p;
p=nullptr;
}
private:
char *p;
};
MyString fun(char* p)
{
return MyString(p);//
}
int main()
{
int k=12;// 12
return 0;
}
moveとforward
move:
move、下位実装は実際には1つのタイプの強転であり、それは1つの左値を右値に強転する.vectorでのpush_back関数の実装では,左値と右値に対して異なる記憶動作を行う必要がある.しかしながら、右値を格納する記号自体が左値であるため(例えば、上記の例では12が右値であるが、kを用いて格納する場合、kは左値である)、右値パラメータに対応する関数を直接呼び出すことができず、moveを用いて右値に強く回転する必要がある.
void construct(T *p, const T& val)//
{
new(p) T(val);// new
}
void construct(T *p, T&& val)
{
new(p) T(std::move(val));//
}
void push_back(const T& val)//
{
if(full())
expand();
construct(_last,val);
_last++;
}
void push_back(T&& val)//
{
if(full())
expand();
construct(_last,std::move(val));// construct
_last++;
}
forward:
上記のコードは,2つのパラメータに直面する1つの機能を実現するために,C++では関数テンプレートで完全に最適化できる繰返し率の高い2セグメントコードを用いたことを見ることができる.forwardでは、パラメータが左か右かを自動的に認識できます.(意味:タイプの完全な転送)したがって、コードは次のように最適化できます.
template<typename Ty>
void construct(T *p, Ty&& val)
{
new(p) T(std::forward<Ty>(val));
}
template<typename Tk>
void push_back(Tk&& val)//
//& &&==>& && &&==>&&
{
if(full())
expand();
construct(_last,std::forward<Tk>(val));// val
_last++;
}```