エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

C++で整数値を返したり文字列を返したりする

#include <string>
#include <iostream>

template<int N, bool is_string>
struct this_is_a_int_or_string;

template<int N>
struct this_is_a_int_or_string<N, false> {
    typedef int value_type;
    static const value_type value = N;
};

template<int N>
struct this_is_a_int_or_string<N, true> {
    typedef std::string value_type;
    static const value_type value;
};

template<int N>
const typename this_is_a_int_or_string<N, true>::value_type this_is_a_int_or_string<N, true>::value = "Fizz";

template<int N>
struct Fizz {
    typedef typename this_is_a_int_or_string<N, (N % 3) == 0>::value_type value_type;
    static const value_type value;
};

template<int N>
const typename Fizz<N>::value_type Fizz<N>::value = this_is_a_int_or_string<N, (N % 3) == 0>::value;

template<typename T>
std::string this_is(T);

template<>
std::string this_is(int n) {
    return "int";
}

template<>
std::string this_is(std::string s) {
    return "string";
}

int main(int, char* []) {
    std::cout << Fizz<1>::value << " is " << this_is(Fizz<1>::value) << std::endl;
    std::cout << Fizz<2>::value << " is " << this_is(Fizz<2>::value) << std::endl;
    std::cout << Fizz<3>::value << " is " << this_is(Fizz<3>::value) << std::endl;
    std::cout << Fizz<4>::value << " is " << this_is(Fizz<4>::value) << std::endl;

    return 0;
}

実行。

$ g++ -o this_is_a_int_or_string this_is_a_int_or_string.cpp 
$ ./this_is_a_int_or_string 
1 is int
2 is int
Fizz is string
4 is int

同じ Fizz<N>::value という形でありながら、N の値によって value の値が整数値であったり文字列であったりします。

FizzBuzzクイズ」の実現方法について @Nabetani さんと C++ で書ける書けないという話をした中で、「template でならできるかも」という流れになったので、書いてみました、途中まで。

本当はもう少し先まで書いたのですが…思うところがあって力尽きてしまいました。

「思うところ」は、また後ほど。

いつか読むはずっと読まない:クロニクル

ということなので。

火星年代記 (ハヤカワ文庫SF)

火星年代記 (ハヤカワ文庫SF)

パラダイスバード・クロニクル

パラダイスバード・クロニクル