C++: Hello, World

  • C++
( 更新)

Hello, Worldと一口に言ってもC++には色々な書き方があるもので、、、

正攻法


競プロ勢は書かないでお馴染み

#include <iostream>

int main() {
  std::cout << "Hello, World" << std::endl;
}

C言語風


ちゃんとstd::printfって書いてる人見たことない

#include <cstdio>

int main() {
  printf("Hello, World\n");
}

グローバル変数のコンストラクタ


C++はmain関数より前に色々できてしまう

#include <iostream>

struct Hello {
  Hello() {
    std::cout << "Hello";
  }
} hello_instance;

int main() {
  std::cout << ", World" << std::endl;
}

畳み込み式


可変引数テンプレートはもはや再帰なしにガチャガチャできる

#include <iostream>
#include <utility>

int main() {
  auto chars = std::make_tuple('H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '\n');
  std::apply([](auto... ch) { (std::cout << ... << ch); }, chars);
}

関数ポインタ/メンバ関数ポインタ


C++においてオーバーロードされた演算子は関数なので。

#include <iostream>

int main() {
  std::ostream&(*f)(std::ostream&, const char*) = &std::operator<<;
  std::ostream&(std::ostream::*g)(std::ostream&(*)(std::ostream&)) = &std::ostream::operator<<;
  (f(std::cout, "Hello, World").*g)(std::endl);
}

!?


(コンパイラの実装にもよるが)参照はポインタの糖衣構文とみなせるので、やろうと思えばこう書くこともできなくはない(UB)

#include <iostream>

template<char C>
struct _;

template<char O>
std::ostream& operator<<(std::ostream& os, _<O>&) {
  return os << (char)(O ^0^ 0);
}

template<typename... Args>
void print(Args... args) {
  (std::cout << ... << *args);
  std::cout << std::endl;
}

int main() {
  print(
    (_<'H'>*)nullptr,
    (_<'e'>*)NULL,
    (_<'l'>*)false,
    (_<'l'>*)0,
    (_<'o'>*)'\0',
    (_<','>*)main,
    (_<' '>*)true,
    (_<'W'>*)"Hello, World!!!",
    (_<'o'>*)0xdeadbeef,
    (_<'r'>*)printf,
    (_<'l'>*)'T',
    (_<'d'>*)('o' ^0^ -~- -0- ~-~ +0+ 0-0 *0* 0*0)
  );
}