4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

入出力ストリームに対応しているかどうかを判断するメタ関数

Last updated at Posted at 2017-04-24

概要

C++のSFINAEを利用して、ある型が入力ストリーム、出力ストリームに対応しているかどうかを判断するメタ関数を作成しました。
この記事に載せているコードはC++11に対応したコンパイラで動きます。

ソースコード

is_iostream_compatible.hpp
#include <iostream>
#include <type_traits>
#include <string> //MSVCではこれが必要

//入力ストリームに対応しているかどうかを判断するメタ関数
template<typename T, typename U = void>
struct is_istream_compatible : public std::false_type{};
template<typename T>
struct is_istream_compatible<T, decltype(std::declval<std::istream&>() >> std::declval<T&>(),std::declval<void>())> : public std::true_type{};

//出力ストリームに対応しているかどうかを判断するメタ関数
template<typename T, typename U = void>
struct is_ostream_compatible : public std::false_type{};
template<typename T>
struct is_ostream_compatible<T, decltype(std::declval<std::ostream&>() << std::declval<T&>(),std::declval<void>())> : public std::true_type{};

解説

is_istream_compatibleは入力ストリームに対応しているかどうかを判断するためのメタ関数です。

このメタ関数では、部分特殊化されたクラステンプレートでdecltypeを用いてstd::istreamと型Tに対応する>>演算子の戻り値型を取得しようとしています。
この時、対応する>>演算子が定義されている場合は部分特殊化された、std::true_typeを継承したクラステンプレートが実体化されます。
また、定義されていない場合はSFINAEにより部分特殊化されたクラステンプレートが省かれ、std::false_typeを継承したクラステンプレートが実体化されます。

これによりoperator>>(std::istream&, T&)が定義されているかどうか、つまり入力ストリームに対応しているかどうかを判断しています。

is_ostream_compatibleは出力ストリームに対応しているかどうかを判断するためのメタ関数ですが、is_istream_compatibleと仕組みは同じです。

#動作例

sample.cpp
#include "is_iostream_compatible.hpp"

//入出力ストリームに対応していないクラス
struct NotIOStreamCompatible{};

int main() {
	//std::stringとNotIOStreamCompatibleが入力ストリームに対応しているか確認
	std::cout << is_istream_compatible<std::string>::value << is_istream_compatible<NotIOStreamCompatible>::value << std::endl;
	//intとNotIOStreamCompatibleが出力ストリームに対応しているか確認
	std::cout << is_ostream_compatible<int>::value << is_ostream_compatible<NotIOStreamCompatible>::value << std::endl;
	return 0;
}
出力
10
10

intとstd::stringは入出力ストリームに対応しておりNotIOStreamCompatibleは対応していないので、結果は正しいことがわかります。

今回は直接用いる例を書きましたが、今回作成したメタ関数は他のメタ関数を作ったりテンプレートメタプログラミングを行ったりするときに役に立つと思います。

4
4
0

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
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?