Table of Contents

C++でtry-operatorを実現する

コンパイラ拡張を使う方法

サンプルコード

#define TRY(expr) ({ \
  static_assert(ResultLike<decltype((expr))>);  \
  auto v = (expr);  \
  if (!v) return v;  \
  v;  \
})
#define THROW(expr) return {Throw, (expr)}
Result<int, std::string> f(int x) {
  if (x%2 == 0) {
    THROW("hello");
  }
  return x;
}
Result<int, std::string> g(int x) {
  return 123 + TRY(f(x));
}
 
int main() {
  std::cout << "g(1): " << g(1) << std::endl;
  std::cout << "g(2): " << g(2) << std::endl;
}

標準機能だけで頑張る方法

サンプルコード

#define BEGIN  \
  try {
#define END(E)  \
  } catch (const E& e) { THROW(E {e}); }
#define TRY(expr) ((expr)? (*expr): throw (expr).error())
Result<int, std::string> f(int x)
BEGIN
  if (x%2 == 0) {
    THROW("hello");
  }
  return x;
END(std::string)
 
Result<int, std::string> g(int x)
BEGIN
  return 123 + TRY(f(x));
END(std::string)
 
int main() {
  std::cout << "g(1): " << g(1) << std::endl;
  std::cout << "g(2): " << g(2) << std::endl;
}

例外を使わないために,例外を使わなければならない...