对具有不同返回类型的方法键入擦除 [英] Type erasure for methods with differing in return types

查看:106
本文介绍了对具有不同返回类型的方法键入擦除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否存在某种形式的类型擦除,用于处理具有相同名称和参数但返回不同值的方法,如下面的示例所示( begin code> end )。我不打算在实际使用这个任何地方,我只是想知道是否可能,如果是,如何做。

I was wondering if some form of type erasure exists for dealing with methods that have the same name and arguments but return different values like in my example below (begin and end). I'm not planning on actually using this anywhere I'm just interested in knowing if it's possible, and, if so, how it would be done.

我知道的唯一的类型擦除形式是有一个指向一个纯虚拟概念类的指针a 模型< T> ,它将呼叫转发到底层 T 。但是,这要求所有 T 包含具有完全相同签名的方法,而在我的示例中返回类型不同。至于我可以告诉类似于虚拟模板函数的东西将需要做我要求的,但我可能会缺少一些东西。

The only form of type erasure I know about is having a pointer to a pure virtual concept class which points to a model<T> which forwards calls to the underlying T. However, this requires that all the T's contain methods with the exact same signature, while in my example the return types differ. As far as I can tell something akin to virtual template functions would be needed to do what I'm asking, but I may be missing something.

class Iterable
{
    //how would this be defined?
}

int main(int argc, char *argv[])
{
    vector<int> v = {1, 2, 3, 4, 5};
    set<string> s = {"foo", "bar", "baz"};

    Iterable iterable;

    if(argc == 2) iterable = v;
    else iterable = s;


    for(auto val : it)
    { 
        cout << val << ' ';
    }
}


推荐答案

擦除可以并已在C ++中在不同的上下文中实现。最常用的方法,用于 boost :: any std :: function<签名> std :: thread 和其他是基于非多态类,即类型已擦除对象,其中包含指向接口类型的指针。在内部,在构建,分配期间或每当用户类型被擦除时,界面的实现被实例化和存储。

Type erasure can and has been implemented in C++ in different contexts. The most common approach, which is used in boost::any, std::function< signature >, std::thread and others is based on a non-polymorphic class that is the type erased object, which contains a pointer to an interface type. Internally, during construction, assignment or whenever the user type is erased, an implementation of the interface is instantiated and stored.

作为一个激励简化的例子,创建可打印类型,可用于打印实现运算符< std :: cout 使用类型擦除。为此,我们需要类型 printable ,内部接口 printable_impl_base ,以及实际实现:

As a motivating simplified example, consider that we wanted to create a printable type that can be used to print any type that implements operator<< to std::cout using type erasure. For that we need the type printable, the internal interface printable_impl_base, and the actual implementations:

// regular polymorphic hierarchy:
struct printable_impl_base {
   virtual ~printable_impl_base() {}
   virtual void print() const = 0;
};
template <typename T>
struct printable_impl : printable_impl_base {
   T copy_to_print;
   printable_impl( T const & o ) : copy_to_print( o ) {}
   virtual void print() const {
      std::cout << copy_to_print << std::endl;
   }
};

// type erasure is performed in printable:
class printable {
   std::shared_ptr<printablable_impl_base> p;
public:
   template <typename T>
   printable( T obj ) : p( new printable_impl<T>(obj) ) {}
   void print() const {
      p->print();
   }
};

请注意,模式与常规多态层次结构非常相似,接口对象,它是一个值类型(借用C#中的值类型),它包含实际的多态对象。

Note that the pattern is very similar to a regular polymorphic hierarchy, with the difference that an interface object is added that is a value type (borrowing the term value type from C#), that holds the actual polymorphic objects inside.

看这个方法,它似乎有点简单和无用,但这是驱动 boost :: any (内部接口只是一个typeid的燃料) , std :: function< void()> (内部接口是它实现 void operator())或 shared_ptr< (接口是删除方法,放弃资源)。

Looking at it this way, it seems kind of simplistic and useless, but that is the fuel that drives boost::any (the internal interface is only a typeid), std::function< void () > (the internal interface is that it implements void operator()), or shared_ptr<> (the interface is the deleter method, that relinquishes the resource).

有一种特定的不同类型的擦除,需要用实现类型擦除的类型来完成它是破坏它:使用临时并绑定到一个常量引用...但这是非常具体的,如果你想要你可以阅读它在这里:http://drdobbs.com/cpp/184403758

There is one specific different type of type erasure when the only thing that needs to be done with the type that implements type erasure is to destroy it: use a temporary and bind it to a constant reference... But this is very specific, if you want you can read about it here: http://drdobbs.com/cpp/184403758

在特定情况下,您是在问题中谈论它有点复杂,因为你不想擦除单一类型,而是一对夫妇。 Iterable 接口必须擦除其内部拥有的容器的类型,并且这样做必须提供它自己的迭代器,它必须对迭代器执行类型擦除容器。不过,这个想法基本上是一样的,只是更多的工作要做。

In the specific case that you are talking about in the question it is a bit more complex, because you don't want to erase a single type, but rather a couple of them. The Iterable interface must erase the type of the container that it internally holds, and in doing so it has to provide it's own iterators that have to perform type erasure on the iterators from the container. Still, the idea is basically the same, just more work to do to implement.

这篇关于对具有不同返回类型的方法键入擦除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆