gcc 4.7 にユーザ定義リテラルが実装されていた

ついに!いつの間にか実装されていたみたいです。


バイナリはここら辺から落としてきました。

[ソース]

#include <iostream>
#include <type_traits>

template<unsigned long long acc, char ...cs>
struct binary_impl
    : std::integral_constant<unsigned long long, acc>{};

template<unsigned long long acc, char c, char ...cs>
struct binary_impl<acc, c, cs...>
    : binary_impl<(acc << 1) + (c == '0' ? 0 : c == '1' ? 1 : throw), cs...>{};

template<char ...cs>
constexpr
unsigned long long
operator "" _b(){
    return binary_impl<0, cs...>::value;
}


template<unsigned long long acc, char ...cs>
struct atoi_impl
    : std::integral_constant<unsigned long long, acc>{};

template<unsigned long long acc, char c, char ...cs>
struct atoi_impl<acc, c, cs...>
    : atoi_impl<(acc * 10) + (c - '0'), cs...>{};

template<char ...cs>
constexpr
std::integral_constant<unsigned long long, atoi_impl<0, cs...>::value>
operator "" _i(){
    return std::integral_constant<unsigned long long, atoi_impl<0, cs...>::value>{};
}


int
main(){
    static_assert(11001_b == 25, "");
    std::cout << 110100_b << std::endl;
    
    // 値によって戻り値型を変える事ができる
    static_assert(std::is_same<
        decltype(10_i), std::integral_constant<unsigned long long, 10>
    >::value, "");

    static_assert(std::is_same<
        decltype(1213_i), std::integral_constant<unsigned long long, 1213>
    >::value, "");

    return 0;
}

[出力]

52

やりました!新しいおもちゃが手に入りました!


ユーザ定義リテラルは template で受け取るので、値から型を作ることが出来ます。
とりあえず、以前作った constexpr lambda だと

static_assert(decltype(arg1 + 82131_i)()(3) == 82134, "");

みたいに使うことができます。
これで、型の定義がだいぶ楽になりますね!