C++編で扱っている C++ は 2003年に登場した C++03
という、とても古いバージョンのものです。C++ はその後、C++11 -> C++14
-> C++17 -> C++20 -> C++23 と更新されています。
なかでも C++11 での更新は非常に大きなものであり、これから C++
の学習を始めるのなら、C++11
よりも古いバージョンを対象にするべきではありません。特に事情がないなら、新しい
C++ を学んでください。 当サイトでは、C++14 をベースにした新C++編を作成中です。
問題① フィールドの幅が 10 で、つねに右寄せに出力する myformatマニピュレータを自作してください。
std::endlマニピュレータの実装を参考にして、自作の myformat関数を定義します。
#include <iostream>
namespace {
template <typename T, typename Traits>
std::basic_ostream<T, Traits>& myformat(std::basic_ostream<T, Traits>& os)
{
.width(10);
os.setf(std::ios::right, std::ios::adjustfield);
osreturn os;
}
}
int main()
{
std::cout << "xyz" << std::endl;
std::cout << myformat << "xyz" << std::endl;
}
実行結果:
xyz
xyz
問題② myformatマニピュレータを改造して、以下のようにフィールドの幅を指定できるようにしてください。
std::cout << myformat(10) << "xyz" << std::endl;
引数があると、標準で定義されている operator<< に渡す関数ポインタの型と適合しないため、関数のままでは実装できません。
解決方法の1つとしては、マニピュレータをクラスとして定義することで、この場合、メンバ変数に情報を保存しておけます。また、これに合わせて、operator<< のオーバーロードを用意します。
#include <iostream>
namespace {
class myformat {
template <typename T, typename Traits>
friend std::basic_ostream<T, Traits>& operator<<(std::basic_ostream<T, Traits>& os, const myformat& fmt);
public:
(int width) :
myformat(width)
mWidth{}
private:
int mWidth;
};
template <typename T, typename Traits>
std::basic_ostream<T, Traits>& operator<<(std::basic_ostream<T, Traits>& os, const myformat& fmt)
{
.width(fmt.mWidth);
os.setf(std::ios::right, std::ios::adjustfield);
osreturn os;
}
}
int main()
{
std::cout << "xyz" << std::endl;
std::cout << myformat(5) << "xyz" << std::endl;
std::cout << myformat(10) << "xyz" << std::endl;
}
実行結果:
xyz
xyz
xyz
問題③ myformatマニピュレータは、フィールドの幅をテンプレート実引数で指定する形にすると、動的な変更はできなくなりますが、より単純に実装できます。以下のように使用できる myformatマニピュレータを作成してください。
std::cout << myformat<10> << "xyz" << std::endl;
フィールドの幅の指定を行う場所が、関数の実引数で無くなったため、標準の operator<< が機能できます。
#include <iostream>
namespace {
template <int WIDTH, typename T, typename Traits>
std::basic_ostream<T, Traits>& myformat(std::basic_ostream<T, Traits>& os)
{
.width(WIDTH);
os.setf(std::ios::right, std::ios::adjustfield);
osreturn os;
}
}
int main()
{
std::cout << "xyz" << std::endl;
std::cout << myformat<5> << "xyz" << std::endl;
std::cout << myformat<10> << "xyz" << std::endl;
}
実行結果:
xyz
xyz
xyz
新規作成。
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |