64ビットの符号付き整数型
64ビット固定の場合はlong longよりも推奨される
int64_t x = 0LL;
ソフトウェアエンジニアの技術ブログ:Software engineer tech blog
随机应变 ABCD: Always Be Coding and … : хороший
64ビットの符号付き整数型
64ビット固定の場合はlong longよりも推奨される
int64_t x = 0LL;
constexprを使わないケース
### 変数
– constでない変数
– クラスのメンバ変数
– 標準入力などの非constexpr関数を用いて計算する値
– 引数などのconstexprでない可能性がある値を用いて計算する値
### 関数
– inline化できない関数
– 引数でもthisでもない非constexprな外側の変数を参照する操作を含む関数
– 引数でもthisでもない外側に副作用を及ぼすような操作を含む関数
#include
auto answer() {return 42;}
constexpr auto auto_constexpr() {return 42;}
constexpr auto answer_print(){
return 42;
}
int main(){
const expr auto b = answer_constexpr();
std::cout << /* a << ", " << */ b << /* ", " << c << */ std::endl; return 0; } [code]
key, valueの連想配列class
struct Person { public: Person(const string &name, int height) : m_name(name) , m_height(height) {} public: string m_name; int m_height; } ... map<Person, int> mp; Person p("aaa", 180); mp[p] = 123;
符号付き、符号なしで型の指定ができる
int8_t、int16_t、int32_t、int64_t、uint8_t、uint16_t、uint32_t、uint64_t、int_fast8_t、int_fast16_t、int_fast32_t、int_fast64_t、uint_fast8_t、uint_fast16_t、uint_fast32_t、uint_fast64_t、int_least8_t、int_least16_t、int_least32_t、int_least64_t、uint_least8_t、uint_least16_t、uint_least32_t、uint_least64_t、intmax_t、uintmax_t、intptr_t、uintptr_t
それにしても多いですね
good_morning.hpp
#ifndef GOOD_MORNING_H #define GOOD_MORNING_H void good_morning(); #endif
good_morning.cpp
#include <iostream> #include "good_morning.hpp" void good_morning() { std::cout << "Good Monring!" << std::endl; }
main.cpp
#include "hello.hpp" #include "good_morning.hpp" int main(){ hello(); good_morning(); }
$ g++ -c hello.cpp good_morning.cpp
$ ar rvs libgreetings.a hello.o good_morning.o
ar: creating libgreetings.a
a – hello.o
a – good_morning.o
$ g++ main.cpp libgreetings.a
$ ./a.out
Hello!
Good Monring!
C++におけるファイルの分割はクラス定義単位で行う
### ヘッダファイル
マクロ定義、型定義、プロトタイプ宣言の3つを書くのが基本
C++ではクラスを利用するには、そのクラスが提供するヘッダファイルを取り込む必要がある
以下のようなファイルがあったとする
class POS { private: int x; int y; public: POS(); int setPos(int tmpx, int tmpy); } POS::POS(){ x = 0; y = 0; } int POS::setPos(int tmpx, int tmpy){ x = tmpx; y = tmpy; return 0; }
これを分割する場合
POS.h
#ifndef POS_H #define POS_H class POS { private: int x; int y; public: POS(); int setPos(int tmpx, int tmpy); } #endif
POS.cpp
#include "POS.h" POS::POS(){ x = 0; y = 0; } int POS::setPos(int tmpx, int tmpy){ x = tmpx; y = tmpy; return 0; }
つまり、最初にheader情報を見て、全体の流れを理解してからソースファイルを見ていくのね。※以前はcppを先に見て、.hは付加情報かと思っていました…orz
HeadersSyncState::ProcessingResult HeadersSyncState::ProcessNextHeaders(const
std::vector
で、ProcessingResult ProcessNextHeaders となっているのは、headerssync.hで、ProcessingResultの構造体を示していたので、このProcessingResultの型で返却して欲しい という書き方なのね。
struct ProcessingResult { std::vector<CBlockHeader> pow_validated_headers; bool success{false}; bool request_more{false}; };
Readmeを読むと以下のように書いている
A script to generate optimal parameters for the headerssync module (src/headerssync.cpp). It takes no command-line
options, as all its configuration is set at the top of the file. It runs many times faster inside PyPy. Invocation:
つまり、node間でのヘッダー情報のやり取りのことだ。c++ファイルのヘッダではない。stateで、 PRESYNC、REDOWNLOAD、FINALとある。
src/headerssync.h, src/headerssync.cpp を見てみる。
### headerssync.h
A compressed CBlockHeader, which leaves out the prevhash
HeadersSyncState
We wish to download a peer’s headers chain in a DoS-resistant way.
* – In the first download phase, called pre-synchronization, we can calculate
* the work on the chain as we go (just by checking the nBits value on each
* header, and validating the proof-of-work).
In phase 1 (presync)
In phase 2 (redownload)
#### headerssync.cpp
// The two constants below are computed using the simulation script in
// contrib/devtools/headerssync-params.py.
m_max_commitments = 6*(Ticks
downloadはこれでやってる?
if (m_current_chain_work >= m_minimum_required_work) { m_redownloaded_headers.clear(); m_redownload_buffer_last_height = m_chain_start->nHeight; m_redownload_buffer_first_prev_hash = m_chain_start->GetBlockHash(); m_redownload_buffer_last_hash = m_chain_start->GetBlockHash(); m_redownload_chain_work = m_chain_start->nChainWork; m_download_state = State::REDOWNLOAD; LogPrint(BCLog::NET, "Initial headers sync transition with peer=%d: reached sufficient work at height=%i, redownloading from height=%i\n", m_id, m_current_height, m_redownload_buffer_last_height); }
downloadのstatusに応じて処理しているのはわかるが、getHashの処理とかはheaderssync.cppの中には書いてないように見えるがどこでやってるんだろうか?
あと、基本的に、HeadersSyncState::${処理}と書かれていますね。
なんか凄いな…
クラスの相互参照における問題
A.h
#ifndef _A_H_ #define _A_H_ #include "B.h" class A { B* m_bB; ... } #endif // _A_H_
ifndef, define, endifは重複回避
B.h
#ifndef _B_H_ #define _B_H_ #include "B.h" class B { A* m_bA; ... } #endif // _B_H_
お互いに参照していると、いつまで経っても参照が終わらなくなってしまう
#ifndef _A_H_ #define _A_H_ class B; class A { private: B* m_bB; public: A(); void foo(); void bar(); ... } #endif // _A_H_
#ifndef _B_H_ #define _B_H_ class A; class B { private: A* m_bA; public: B(A* pA); void hoge(); } #endif // _B_H_
includeはしていないのだが、うーん、なんかよくわからんな…
std::vector<int> v; for(std::vector<int>::const_iterator it = v.begin(), e=v.end(); it != e; ++it){ std::cout << *it << std::endl; }
c++11の範囲for文を使うと以下のように書ける
std::vector<int> v; for(const auto& e: v){ std::cout << e << std::endl; }
### 範囲for文(range-based for statement)
配列やコンテナなど複数の要素を持つものから、全ての要素に含まれる値を取り出して処理する
#include <iostream> using namespace std; int main() { int a[] = {1, 2, 3, 4, 5}; int sum = 0; for(int x : a){ sum += x; } cout << "sum = " << sum << end; return 0; }
vector要素の出力
vector<string> v(5); for (int i = 0; i < v.size(); i++){ string& x = v[i]; cin >> x; }
autoは型推論を行うキーワード
vector<string> v(5); for (auto& x : v){ cin >> x; }
C++ではクラスの定義とそのメンバ関数の定義をヘッダファイルとソースファイルで分割するのが一般的である
### ファイルを分割していない例
c.hpp
#ifndef C_HPP #define C_HPP class c { private: int m_value; public: int get() { return m_value; } void set(int const value){ m_value = value; } }; #endif
### ファイルを分割した例
c.hpp
#ifndef C_HPP #define C_HPP class c { private: int m_value; public: int get(); void set(int const value); }; #endif
c.cpp
#include "c.hpp" int c::get(){ return m_value; } void c::set(int const value){ m_value = value; }
インラインで書くこともある
#ifndef C_HPP
#define C_HPP
class c {
private:
int m_value;
public:
int get();
void set(int const value);
};
inline int c::get(){
return m_value;
}
inline void c::set(int const value){
m_value = value;
}
#endif
bitcoinのソースコードで、基本hppとcppのファイル構造になっていたが、謎が解けた。