LoginSignup
2
1

More than 5 years have passed since last update.

整数型の大きさで SFINAE の練習

Posted at

しばらく前に「整数型の大きさで関数をオーバーロードする方法」という表題で記事が投稿されました。 これは興味深い話題です。 同じ大きさで同じ符号の整数型は混同しても (C/C++ の世界では) おおよそ問題ないにもかかわらず、型機構の(もと)では区別されてしまます。 それをあらためて同じように扱えるようにするというのは屋上屋(おくじょうおく)()すようではありますが、型機構に保護されていることとの二律背反であり、 C++ らしさを象徴しているようにも思います。

さて、元記事では長くならないようにマクロで書かれていますが、あえて C++ らしく書くとすればどうあるべきなのだろうと SFINAE の練習を兼ねて書いてみました。

conversion_rank_traits.h
// -*- mode: c++ -*-
#ifndef HEADER_1301cf13c7f0041bbbbb364e6d8094c7
#define HEADER_1301cf13c7f0041bbbbb364e6d8094c7

#include <type_traits>

template<bool> class is_true;
template<> class is_true<true> : public std::true_type {};
template<> class is_true<false> : public std::false_type {};

template<class T, class U>
using is_same_size = is_true<sizeof(T)==sizeof(U)>;

template<class T, class U>
using is_same_signed =
  is_true<std::is_signed<T>::value==std::is_signed<U>::value>;

template<class T, class U>
using is_same_rank_integral =
  is_true<std::is_integral<T>::value
          && std::is_integral<U>::value
          && is_same_size<T,U>::value
          && is_same_signed<T,U>::value>;

template<class T, class U, class V=void>
using enable_if_same_rank_integral =
  typename std::enable_if<is_same_rank_integral<T, U>::value, V>;

#endif

以下のように使います。

sample.cpp
#include <iostream>
#include "conversion_rank_traits.h"

#ifdef __WIN32__
#include <windows.h>
#else
typedef unsigned long DWORD;
#endif

template<class T>
typename enable_if_same_rank_integral<std::uint8_t, T>::type f(T) {
  std::cout << "uint8_t\n";
}

template<class T>
typename enable_if_same_rank_integral<std::uint16_t, T>::type f(T) {
  std::cout << "uint16_t\n";
}

template<class T>
typename enable_if_same_rank_integral<std::uint32_t, T>::type f(T) {
  std::cout << "uint32_t\n";
}

template<class T>
typename enable_if_same_rank_integral<std::uint64_t, T>::type f(T) {
  std::cout << "uint64_t\n";
}

int main(void) {
  DWORD x = 12345;
  f(x);
  return 0;
}

C++ の一般的な作法に(のっと)ろうとするとどうしても冗長にならざるを得ないようです。 冗長であるかわりに、小さい単位で名前を付けながら段階的な構築をしやすいという利点もあります。 完成形が明確にわかっている場合は一気に書いてしまって良いと思いますが、試行錯誤するにあたっては必要そうな部品を徐々に作っていった方がやりやすいように感じました。

2
1
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1