gpt4 book ai didi

c++ - 如何将类型删除技术应用于现有类型?

转载 作者:行者123 更新时间:2023-11-28 06:47:51 25 4
gpt4 key购买 nike

众所周知,如果我们是从头开始设计类型系统,那么我们可以使用类型删除技术来实现多态性。但是,我们应该如何将类型删除技术应用于现有类型,例如以下情况?

struct A
{
int f()
{
return 1;
}
};

struct B
{
int f()
{
return 2;
}
};

template<class TypeForOtherUse> // Don't put A or B here
struct C
{
C(A a)
: obj_of_A_or_B(a)
{}

C(B b)
: obj_of_A_or_B(b)
{}

int g()
{
return obj_of_A_or_B.f();
}

/* ??? What should be put here ??? */ obj_of_A_or_B;
};

最佳答案

boost有一个完整的类型删除库,可让您选择要删除的内容。

但是,像上面这样的简单情况可以按如下方式完成:

// The interface detailing what we support.  Move is always supported.
// only need clone if we want to copy:
struct IImpl {
virtual std::unique_ptr<IImpl> clone() const = 0;
virtual int f() = 0;
virtual ~IImpl() {}
};

// The pImpl<T> class writes custom code to type erase a type T.
// you can specialize it for extreme cases: ie, suppose for some type X
// you want f() to invoke g() -- then you can specialize Impl to do that.
// (that is a bit of a toy example, and a bad one, but imagine std::function
// specialized for method pointers such that `this` is turned into the first
// argument)
template<class T>
struct Impl:IImpl {
T t;
virtual std::unique_ptr<IImpl> clone() const override {
return std::unique_ptr<IImpl>( new Impl(t) );
}
virtual int f() const override {
return t.f();
}
virtual ~Impl() {}
template<typename...Us>
explicit Impl( Us&&... us ): t(std::forward<Us>(us)...) {}
// copy is handled by clone. move is handled by unique_ptr:
Impl( Impl const& ) = delete;
Impl& operator=( Impl const& ) = delete;
};

// the value-semantics class that type-erases:
struct TypeErased {
std::unique_ptr<IImpl> pImpl; // where the work is mostly done
int f() { return pImpl->f(); } // forward to where the work is mostly done
template<typename T, typename... Us> // pass T explicitly, allow construction from other types
void emplace( Us&&... us ) { pImpl.reset( new Impl<T>(std::forward<Us>(us)...) ); }
template<typename T> // like std::function, sucks in similar ways
explicit TypeErased( T&& t ): pImpl( new Impl<typename std::decay<T>::type>(std::forward<T>(t)) {};
TypeErased(TypeErased&&) = default;
TypeErased(TypeErased const&o): pImpl( o.pImpl?o.pImpl->clone():nullptr ) {}
TypeErased(TypeErased const&&o):TypeErased(o) {} // delegate to const&, no need to cast here
TypeErased(TypeErased&o):TypeErased( const_cast<TypeErased const&>(o) {} // delegate to const&

TypeErased& operator=(TypeErased&&) = default; // moving the unique_ptr does the right thing
TypeErased& operator=(TypeErased const&o) { // copy-swap idiom
TypeErased tmp(o);
this->swap(tmp);
return *this;
}
void swap( TypeErased& o ) {
std::swap( pImpl, o.pImpl );
}
};

// You can make this a template on other types, but I'll omit it, as it just fuzzies things up:
struct C {
C(A a): erased(a) {}
C(B b): erased(b) {}
int g() {
return erased.f();
}
TypeErased erased;
};

没有编译,但我又读了一遍,去掉了大部分错别字。

关于c++ - 如何将类型删除技术应用于现有类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24631937/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com