【问题标题】:C++ right way of returning a generic collection of typeC++ 返回泛型类型集合的正确方法
【发布时间】:2012-02-25 01:30:45
【问题描述】:

我是 C++ 新手,不幸的是,我无法停止思考 C#(我以前的语言)。 我阅读了一些书籍、论坛和 C++ 参考网站,但我找不到我的问题的答案,所以我想我不妨先在这里尝试一下,然后再放弃并写一些丑陋的东西。

好的,我们可以开始了。 我有一个带有抽象方法 succesorsFunction 的类,我希望它返回一个指向 State 的指针集合。我不想强迫实现者使用特定的容器;我宁愿让他们选择(向量、列表等)。

所以它看起来像这样:

class Problem
{
public:
    virtual list<const State*>::iterator succesorsFunction(const State &state, list<const State*>::iterator result) const = 0;
};

这里的问题是列表的显式使用。你在 C++ 中是如何做到的?

我想过使用模板,但后来遇到了两个问题: 1)看起来你不能用抽象方法来做(或者我错了吗?) 2) 如何告诉模板它应该包含指向 State 的指针?

【问题讨论】:

  • Boost.Range 的类型擦除范围在这里可能会有所帮助。
  • 你能扩展一下这个功能和它是虚拟应该实现的吗?可能有其他方法。
  • 所以你想返回类似于IEnumerable&lt;State&gt;的东西?
  • @GeorgFritzsche '问题' 是一个接口。我真正想做的是返回一个通用容器而不是一个具体的容器。
  • @svic 完全正确。我觉得我不应该尝试在 C++ 中这样做,但是如何返回某种类型的集合?

标签: c++ algorithm templates generics containers


【解决方案1】:

您不能在 C++ 中基于返回类型重载方法。

此外,C++ 中的“容器”没有相同的基础(如 Java 中的 Collection),因此您不能返回通用容器。

恐怕没有干净的方法可以做到这一点。

我只会写重载(通过参数)或不同的函数名。

对于您的问题:

1) 你可以。是什么让你认为你做不到?

2) 与您声明 list 的方式相同:list&lt;const State*&gt; - const 是可选的。

【讨论】:

  • 我认为他没有说过返回值重载;有多个实现具有相同的返回类型。他只是希望返回类型足够通用,不会限制实现。
  • @ErnestFriedman-Hill 他的问题是他想返回一个集合并且他不想限制该集合(尽管代码返回一个迭代器)。
  • ...它没有说明返回类型的重载。
  • 我认为 1) 指的是模板化的虚函数,这是你不能做到的。
  • 您可以处理通用容器,您只需要带有迭代器的模板函数。 1) Xeo 所说的。 2) 他的意思是通用容器。
【解决方案2】:

如果您真的想强制使用 STL 容器,请尝试以下操作:

template <template <typename, 
                    typename = std::allocator<const State *> > class Container>
 Container<const State*> successorsFunction(const State &state, const Container<const State*> &c) const
 {
    // return something useful.
 }

如果你坚持让这个函数是虚拟的,那么它就不能是成员函数模板,只需用你打算支持的类型重载它,然后你就可以将它们设为虚拟。

【讨论】:

    【解决方案3】:

    你不能有一个虚拟的成员函数模板,但你可以尝试像这样实现友元泛型函数:

    template <typename yourType>
    yourType& succesorsFunction(const State &a, yourType &result){//Your return type can be without reference
        //Your body
        return result;
    }
    

    如果您使用 vector&lt;State&gt; a 参数调用您的函数,例如:

    sucessorsFunction(b,a);// b is your State object
    

    推演过程会自动得出yourType实际上是vector&lt;State&gt;类型的结论,我认为这可以解决你的问题。此外,该架构还可以让您创建新的类类型 MyVector(其中包含 States 的数组)并将 MyVector 对象传递给 succesorsFunction

    【讨论】:

    • 我尝试这样做,但它不适用于抽象方法。我不妨在最后删除 =0 并完成它。感谢您的回复
    • @wolfovercats 如果您不知道类型,您将如何填充结果?
    • @LuchianGrigore 我知道类型;这是州*。
    • 好的,我明白你的意思了。我将使用 push_back()。这样他们仍然可以在向量、列表和队列之间进行选择。好的,也许我应该将其限制为向量;我不确定这是否值得所有的麻烦
    • 这就是我的意思。一个基本的Collection 会很棒,你可以将add 元素添加到任何东西上。在 C++ 中,您需要 push_back 或 add 或 insert 等...您可以专门化此功能,但我认为这不值得。
    【解决方案4】:

    这只是对C.T's 答案的详细说明。请记住,如果您返回一个指针容器,那么您将不得不显式释放它们或使用std::unique_ptr
    仅供参考.. 因为您来自 C# 背景。

    您也可以使用 State 或对其进行模板化。

    template<typename Type, 
             template< typename, typename = std::allocator<Type*> > class Container 
            >
    Container<Type*> Successor(const Type& x)
    {
        Container<Type*> cont;
        // something.
        cont.push_back(new Type(x));
        return cont;   
    }
    

    然后调用它

    vector<State*> states = Successor<State, vector>(State(10));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多