目的
コマンドライン引数より入力した dotted decimal形式のipv4アドレス
例:192.168.1.2
を、バイト配列に変換しようと思いました
もちろん .でsplitして自力で分解しても良いのですが
asioの機能を使うべきでしょう
それには boost::asio::ip::address_v4 を使えば良いようです
ここが Referenceです
ところが上手くいかなかった
コンストラクタは、default constructor、バイト配列、long値、コピーコンストラクタ
のみで、dotted decimal文字列からは構築出来ないので
default constructorで構築し、from_string で設定し
to_xxx で変換
方針は決まったので早速 コーディング
boost::asio::ip::address_v4 ipp;
ipp.from_string("192.168.1.2");
std::cout << "to_string() " << ipp.to_string() << std::endl;
std::cout << "to_ulong() " << ipp.to_ulong() << std::endl;
auto bt(ipp.to_bytes());
std::cout << "to_bytes() " << (int)bt[0] << "." << (int)bt[1] << "." << (int)bt[2] << "." << (int)bt[3] << std::endl;
実行結果
to_string() 0.0.0.0
to_ulong() 0
to_bytes() 0.0.0.0
・・・ あれ?? ダメじゃん
ip::address_v4 を調べる
仕方ないので コードを調べます
引数が const char*、const char*, error_code&、 const string&、 const string&, error_code
と4つオーバーライドがありますが どれも同じなので
/// Create an address from an IP address string in dotted decimal form.
BOOST_ASIO_DECL static address_v4 from_string(const char* str);
address_v4 address_v4::from_string(const char* str)
{
boost::system::error_code ec;
address_v4 addr = from_string(str, ec);
boost::asio::detail::throw_error(ec);
return addr;
}
ん??? staticメソッド。
from_stringは factoryパターンのようです
完成版
ということで、factoryパターンに対応させます
auto ipp = boost::asio::ip::address_v4::from_string("192.168.1.2");
std::cout << "to_string() " << ipp.to_string() << std::endl;
std::cout << "to_ulong() " << ipp.to_ulong() << std::endl;
auto bt(ipp.to_bytes());
std::cout << "to_bytes() " << (int)bt[0] << "." << (int)bt[1] << "." << (int)bt[2] << "." << (int)bt[3] << std::endl;
実行結果
to_string() 192.168.1.2
to_ulong() 3232235778
to_bytes() 192.168.1.2
うまくいきましたね。
悩み
from_string()の戻りは この場合一時オブジェクトになり 右辺値参照になるんでしたっけ?
なので
auto ipp = std::move(boost::asio::ip::address_v4::from_string("192.168.1.2"));
とは 書いていないけど どうだっけ・・
あと、今回は代入演算子で行っているが コピーコンストラクタの方が良いのか?
あるいは 参照で受け取るのか
イマイチ 右辺値参照を本格的に理解していないので
疑問は残ったので
もっと勉強が必要だ