LoginSignup
1
0

More than 1 year has passed since last update.

# C++ でプロパティーを実現する方法パート2

Last updated at Posted at 2022-12-27

改めてプロパティーをC++で実現する方法を考えてみました。 clang ではメンバーのアドレス/オフセットが静的に扱えないので empty base optimization(EBO) で実現する形にしました。 型は分かれますが醜悪なマクロを使いません。

#include <iostream>
#include <type_traits>
#include <string>

template<class T>
struct PropertyUtil {
    // empty base
    PropertyUtil(const PropertyUtil&) = delete;
    PropertyUtil(PropertyUtil&&) = delete;
    PropertyUtil& operator=(const PropertyUtil&) = delete;
    PropertyUtil& operator=(PropertyUtil&&) = delete;

protected:
    PropertyUtil() {}

    constexpr auto operator->() noexcept -> T* {
        return reinterpret_cast<T*>(this);
    }

    constexpr auto operator->() const noexcept -> const T* {
        return reinterpret_cast<const T*>(this);
    }
};

template<typename T>
struct FooProperty {
    // empty base
    FooProperty() {}
    FooProperty(const FooProperty&) {};
    FooProperty(FooProperty&&) {};
    FooProperty& operator=(const FooProperty&) {};
    FooProperty& operator=(FooProperty&&) {};

    [[no_unique_address]] struct : PropertyUtil<T> {
        operator int() noexcept {
            return this[0]->value_;
        }
        auto operator=(int n) noexcept -> int {
            this[0]->value_ = n;
            return n;
        }
    } value;
};
struct Dummy {};
static_assert(std::is_empty<FooProperty<Dummy>>::value);

struct Foo : FooProperty<Foo> {
private: 
    int value_ = 123;
    friend struct FooProperty<Foo>;  
    friend int main();
};

int main()
{
    auto a = Foo();
    //auto _ = a;
    std::cout << a.value << std::endl;
    a.value = 256;
    std::cout << a.value << std::endl;   
}
1
0
1

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
1
0