draemonash2のメモ書き
Human::Human(const Human& human)
virtual void speak();
virtual void speak() = 0;
using integer = int;
namespace sub = module::submodule;
using aaa::show; //ここから後に記述されるshowは、aaa::showと認識される。
その場合、using宣言により基底クラスのメンバ関数を使用することを宣言することで解消できる。
class Derived : public Base
{
public:
using Base::foo; // 基底クラスのfoo()を呼び出せるようにする
void foo(int v); // 派生クラスで追加したオーバーロード
};
using namespace module;
template <int i>
template <typename A, typename B, typename C>
struct Tuple
{
A a;
B b;
C c;
template <>
struct Tuple<int, void, float>
{
int a;
float c;
template <typename A, typename C>
struct Tuple<A, void, C>
{
A a;
C c;
しかし、以下のようにcpp内にプログラマが型を指定して実体化するよう指示する(=明示する)事により関数の中身をcppファイルへ分離できるようになる。
template int max<int>(int a, int b);
template double max<double>(double a, double b);
int x = 3;
int& r = x;
auto a = r; // aの型はint
decltype(r) b = r; // bの型はint&
decltype(auto) c = r; // cの型はint&
まとめ
型名 | コピー | ムーブ | アクセス | 所有権 | 特徴 |
---|---|---|---|---|---|
unique_ptr | × | ○ | ○ | 単一 | 軽量・シンプル |
shared_ptr | ○ | ○ | ○ | 共有 | コピー可能だがオーバーヘッドが存在 |
weak_ptr | ○ | ○ | △ | - | 所有権を持たずshared_ptrへの参照を保持 |
例
char a = 2;
cout << a << endl;
原因
例)イテレータ非使用時
int arr[] = { 1, 3, 9, 4 };
for (int idx = 0; idx != (sizeof(arr) / sizeof(arr[0])); ++idx) {
std::cout << arr[idx] << std::endl;
}
例)イテレータ使用時
int arr[] = { 1, 3, 9, 4 };
for(int* it = std::begin(arr); it != std::end(arr); ++it){
std::cout << *it << std::endl;
}
参照渡しとポインタ渡し
void calc( int x, int &y ) { /* 参照渡し */
y += x;
}
void calc( int x, int *p ) { /* ポインタ渡し */
*p += x;
}
int main( void ) {
calc( x, y ); /* 参照渡し */
calc( x, &y ); /* ポインタ渡し */
}
template class Stack<int>;
()の場合、カンマ演算子として認識されるため、A(std::string)と解釈される
A cp = (42, "0"); // ⑦ エラー。A(int, std::string)の呼び出しにはならない
A cb = {42, "0"}; // ⑧ OK。bbの初期化と同等
縮小変換が禁止されているため、意図しない暗黙変換を検出できる
A ep(pi); // ⑪ OKだがdoubleからfloatへの暗黙変換が行われる
A eb{pi}; // ⑫ エラー。doubleからfloatへは安全に変換できない
変数宣言の際にデフォルトコンストラクタを丸カッコで呼び出すと、コンパイラがそれを関数宣言と認識してしまうという問題を抑制できる
int main()
{
X x();
}
暗黙のコンストラクターの呼び出しを抑制できる
A x = 0; // エラー。暗黙のコンストラクター呼び出しは禁止されている
A y{42}; // OK。明示的なコンストラクター呼び出し
暗黙のコンストラクターの呼び出しは、あくまでコンストラクターの実引数として渡されるだけだが、プログラムが与える印象のせいでミスリードしてしまう
テンプレートの種類と機能の可否
機能 | 仮想関数 | 明示的特殊化 | 部分特殊化 |
---|---|---|---|
関数テンプレート | 不可 | 可 | 不可 |
クラステンプレート | 可 | 可 | 可 |
ソースコード
const auto a = []() {
return 100;
};
std::cout << a() << std::endl; // 100
解説
a
を定義する。その後、a
を()
で呼び出す。ソースコード
const auto b = [] {
return 100;
}();
std::cout << b << std::endl; // 100
解説
{}
内で定義したラムダ式を()
で呼び出して、ラムダ式の返却値を変数b
に格納する。