Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?
@CdecPGL

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

More than 3 years have passed since last update.

概要

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
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
CdecPGL
主にUnityでゲームを制作しています。 ひっそりとDXライブラリ&C++でもゲームを制作しています。 使っている言語はC#、Python、C++
unity-game-dev-guild
趣味・仕事問わずUnityでゲームを作っている開発者のみで構成されるオンラインコミュニティです。Unityでゲームを開発・運用するにあたって必要なあらゆる知見を共有することを目的とします。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
4
Help us understand the problem. What is going on with this article?