GCC和LLVM实现都在对象std::any中存储函数指针any,并使用Op/Action参数调用该函数来执行不同的操作。以下是 LLVM 中该函数的示例:
static void* __handle(_Action __act, any const * __this,
any * __other, type_info const * __info,
void const* __fallback_info)
{
switch (__act)
{
case _Action::_Destroy:
__destroy(const_cast<any &>(*__this));
return nullptr;
case _Action::_Copy:
__copy(*__this, *__other);
return nullptr;
case _Action::_Move:
__move(const_cast<any &>(*__this), *__other);
return nullptr;
case _Action::_Get:
return __get(const_cast<any &>(*__this), __info, __fallback_info);
case _Action::_TypeInfo:
return __type_info();
}
__libcpp_unreachable();
}
Run Code Online (Sandbox Code Playgroud)
注意:这只是一个__handle函数,但每个实现中有两个这样的函数any:一个用于在内部分配的小对象(小缓冲区优化)any,一个用于在堆上分配的大对象。使用哪一个取决于对象中存储的函数指针的值any。
在运行时选择两种实现之一并从预定义的方法列表中调用特定方法的能力本质上是虚拟表的手动实现。我想知道为什么要这样实施。简单地存储指向虚拟类型的指针不是更容易吗? …
这是我想要做的:
我正在开发支持插件的跨平台IDE(Linux和Windows).我需要使用类似于Eclipse提供的适配器框架来支持可扩展性.有关详细信息,请参阅此处,但基本上我需要以下内容:
设Adaptee和Adapted是已经存在的,而我们是不允许以任何方式改变完全无关的类.我想创建一个AdapterManager有方法的类
template <class Adaptee, class Adapted> Adapted* adapt( Adaptee* object);
Run Code Online (Sandbox Code Playgroud)
这将创建Adapted给定实例的实例Adaptee.如何创建实例取决于必须注册的适配器函数AdapterManager.每个新插件都应该能够为任意类型提供适配器功能.
以下是我对可能解决方案的看法以及为什么它不起作用:
C++ 11的RTTI函数和type_info类提供了一种hash_code()方法,它为程序中的每种类型返回一个唯一的整数.看到这里.因此,AdapterManager可以简单地包含给定Adaptee的哈希码的映射,并且Adapter类返回指向适配器函数的函数指针.这使得adapt()上面的函数的实现变得微不足道:
template <class Adaptee, class Adapted> Adapted* AdapterManager::adapt( Adaptee* object)
{
AdapterMapKey mk( typeid(Adapted).hash_code(), typeid(Adaptee).hash_code());
AdapterFunction af = adapterMap.get(mk);
if (!af) return nullptr;
return (Adapted*) af(object);
}
Run Code Online (Sandbox Code Playgroud)
任何插件都可以通过简单地在地图中插入附加功能来轻松扩展框架.另请注意,任何插件都可以尝试使任何类适应任何其他类,并且如果存在相应的适配器函数,则AdapterManager无论注册者是谁,都会成功.
type_info结构的两个单独实例以及可能不同的hash_code()结果,这将破坏上述机制.从一个插件注册的适配器功能可能并不总是在另一个插件中工作.问题: …
我正在尝试编写定义super类型习惯用法的模板类的变体.该类Inherit引入了类型Super来表示可能非常长的超类型,并且还需要知道派生类型New来做一些我没有在这里展示的额外的东西.
如果传递给的类型New不是模板,但是模板失败,则此方法正常.这是一个用clang++-3.8 -std=c++1y -Wall(gcc给出相同的输出)编译的完整示例:
struct SomeBase {};
template<class New, class Base>
struct Inherit : Base {
using Super = Inherit<New, Base>;
};
struct NonTemplate : Inherit<NonTemplate, SomeBase> {
using X = Super;
// compiles and is nice and short
};
template<class T>
struct Template : Inherit<Template<T>, SomeBase>
{
using A = Super;
// error: unknown type name 'Super'; did you mean 'NonTemplate::Super'?
using B …Run Code Online (Sandbox Code Playgroud)