Assignableコンセプトをシミュレートするメタ関数を書こうとして失敗に終わった記録

C++03

#include <boost/static_assert.hpp>

template <class T>
struct assignable {
private:
    typedef char yes;
    typedef struct { char arr[2]; } no;

    template <class U>
    static U& ref();

    template <class U>
    static yes test(int)
    {
        ref<U>() = ref<U>();
        return yes();
    }

    template <class U>
    static no test(...);

public:
    static const bool value = sizeof(test<T>(0)) == 1;
};

class A {};

class B {
    int& x_;
    B(int& x) : x_(x) {}
};

int main()
{
    BOOST_STATIC_ASSERT(assignable<A>::value);  // true
    BOOST_STATIC_ASSERT(!assignable<B>::value); // false : エラー!
}


C++0x(GCC 4.4)

#include <boost/static_assert.hpp>

template <class T>
struct assignable {
private:
    typedef char yes;
    typedef struct { char arr[2]; } no;

    template <class U>
    static U& ref();

    template <class U>
    static decltype(static_cast<void>(ref<U>() = ref<U>()), yes()) test(int);

    template <class U>
    static no test(...);

public:
    static const bool value = sizeof(test<T>(0)) == 1;
};

class A {};

class B {
public:
    int& x_;
    B(int& x) : x_(x) {}
};

int main()
{
    BOOST_STATIC_ASSERT(assignable<A>::value);  // true
    BOOST_STATIC_ASSERT(!assignable<B>::value); // false : エラー!
}


http://twitter.com/Cryolite/statuses/5281395771

http://twitter.com/Cryolite/statuses/5281483851

http://twitter.com/Cryolite/statuses/5281509440


GCCN2924に対応してくれればいけるかも。