Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new (ptr) T() == static_cast<T*>(ptr) ? #5920

Closed
ASaltedFishBoy opened this issue Oct 27, 2022 · 3 comments
Closed

new (ptr) T() == static_cast<T*>(ptr) ? #5920

ASaltedFishBoy opened this issue Oct 27, 2022 · 3 comments

Comments

@ASaltedFishBoy
Copy link

ASaltedFishBoy commented Oct 27, 2022

I don't know if this is the right place to ask this question, but I don't know where I can find a discussion environment that is more knowledgeable about the C++ language standard.

I want to implement something like rust's dyn trait


template<template<typename> typename Trait>
class Dyn
{
    struct _SizeCaler:Trait<void>{ void* _p;};
    char _buffer[sizeof(_SizeCaler)];
public:
    template<typename T>
    Dyn(T* value){
        static_assert(std::is_base_of_v<Trait<void>,Trait<T>>
            ,"error Trait T,is not derive from trait<void>"
        );

        static_assert(sizeof(_buffer) >= sizeof(Trait<T>)
            ,"different vtable imple cause insufficient cache"
        );

        new (_buffer)Trait<T>{value}; 
    }
    Trait<void>* operator->(){
        return static_cast<Trait<void>*>(reinterpret_cast<void*>(_buffer));
    }
};

template<template<typename> typename Trait,typename T>
struct DynBase:Trait<void>
{
protected:
    T* self;
public:
    DynBase(T* value):self(value){}
};

struct Point{
    double x,y;
};

struct Rect{
    Point m_leftDown,m_rightUp;
    Rect(Point p1,Point p2){
        m_leftDown = Point{std::min(p1.x,p2.x),std::min(p1.y,p2.y)}; 
        m_rightUp = Point{std::max(p1.x,p2.x),std::max(p1.y,p2.y)}; 
    }
};

template<typename = void>
struct Shape;

template<>
struct Shape<void>
{
    virtual double area() = 0;
};

template<>
struct Shape<Rect> final
    :DynBase<Shape,Rect>
{
    using DynBase<Shape,Rect>::DynBase;
    double area() override{
        return (self->m_rightUp.x - self->m_leftDown.x )
            * (self->m_rightUp.y - self->m_leftDown.y);
    }
};

void printShape(Dyn<Shape> ptr)
{
    std::cout << ptr->area();
}

int main()
{
    Rect r{{1,2},{3,4}};
    printShape(&r);
}

but I found that the c++standard may not be able to derive “new (ptr) T() == static_cast<T*>(ptr)“?
So conversely, “static_cast<T*>(ptr) == new (ptr) T()” cannot prove
Trait<void>* operator->(){ return static_cast<Trait<void>*>(reinterpret_cast<void*>(_buffer)); }

Other attempts
a abstruct class can't be a union member(why?),and I can't use placement new to calculate offset at compile time, because Trait is an abstract class.

@JohelEGP
Copy link
Contributor

I don't think this is fit for this repository.

Sean Baxter is doing just that for Circle. See https://cpplang.slack.com/archives/C21PKDHSL/p1666552169205369. Maybe you can converse there about that. The Slack also has a "standardese" channel where you could ask that question.

@ASaltedFishBoy
Copy link
Author

ASaltedFishBoy commented Oct 27, 2022

I don't think this is fit for this repository.

Sean Baxter is doing just that for Circle. See https://cpplang.slack.com/archives/C21PKDHSL/p1666552169205369. Maybe you can converse there about that. The Slack also has a "standardese" channel where you could ask that question.

thanks

@jwakely
Copy link
Member

jwakely commented Oct 27, 2022

I don't know if this is the right place to ask this question,

It's not. This is for editorial issues in the draft standard.

but I don't know where I can find a discussion environment that is more knowledgeable about the C++ language standard.

This is not a discussion environment.

@jwakely jwakely closed this as not planned Won't fix, can't repro, duplicate, stale Oct 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants