【问题标题】:C++ Initializer_List into Vector of PointersC++ Initializer_List 转换为指针向量
【发布时间】:2014-04-14 14:35:18
【问题描述】:

我一直在尝试简化我的一些代码,尽可能地压缩和简化调用。我一直在尝试做的一件事是将我到处都有的两种常见的重载合并为一个。它们如下:

void MyClass::addSomething(Something & a)
{
   vectorOfSomething.push_back(&a)
}

void MyClass::addSomething(std::vector<Something*> a)
{
   for (unsigned int i = 0; i < a.size(); i++)
      vectorOfSomething.push_back(a[i]);
}

Something 类是抽象的。 vectorOfSomething 是指向Somethings的指针向量。

基本上,不必这样做:

std::Vector mySomethings = {&something1, &something2};
addSomething(mySomethings);

我想这样做:

addSomething({something1, something2});

所以它更类似于第一次重载(用户无需先创建指针向量)。环顾我看到的两种方式,要么是通过:std::initializer_list 要么是可变参数模板,我不怕承认这两种方式对我来说都是完全陌生的。

我已经尝试过使用初始化列表,但在尝试各种事情时遇到了大量错误。我已经设法让函数实际接受列表,但我不太清楚如何让它正确填充向量。主要问题似乎是 init 列表中的值是“const”。

如果有人对如何制作这项工作有任何想法,我将不胜感激!

【问题讨论】:

  • 为什么是指针向量?如果要在向量和原始对象范围之间共享对象的所有权,请考虑使用 std::shared_ptr。拥有指针向量(应该是智能指针,而不是裸指针)的唯一原因是所有权共享(如上所述)和多态性。我在您的代码中都没有看到它们。我为所有权共享付费,但你明确使用指针对我来说很烦人。
  • 所以请向我们展示更多关于您正在训练解决什么问题的背景信息。
  • 在 c++11 中,您可以将语法 addSomething({something1, something2}); 与您已有的函数一起使用:ideone
  • @Manu343726 指针向量的原因是多态性。我正在实现的是在 for 循环中绘制的各种类型的图形列表。抽象库包含绘图功能。我承认到目前为止我还没有研究过这个问题的智能指针,如果我的显式是不好的做法,也许我会这样做!
  • @user2079303 看看,确实如此!这使得向量的使用不那么烦人了,但我仍然希望有一个解决方案,它可以在对象不是指针的情况下使用 addSomething({something1, something2})。

标签: c++ pointers vector std


【解决方案1】:

类似这样的:

#include <iostream>
#include <initializer_list>
#include <vector>
#include <list>

struct MyClass {
    template <typename It >
    void Add( It b, It e ) {
        data_.insert( end(data_), b, e );
    }

    void Add( std::initializer_list<int> const & elems ) { 
        Add( begin(elems), end(elems) ); 
    }

    template <typename T>
    void Add( T const & cont ) {
        Add( begin(cont), end(cont) ); 
    }

    std::vector<int> data_;

    friend std::ostream & operator<<( std::ostream & os, MyClass const & mc ) {
        for( auto & e : mc.data_ )
            os << e << " ";
        return os;
    }
};

int main() {
    MyClass foo;

    foo.Add( { 1, 3 });

    std::vector<int> v { 1,2};
    foo.Add( v );

    std::list<int> l { 4,5};
    foo.Add( l );

    std::cout << foo;
}

编译器不能推断初始化器列表的模板参数,特化必须是显式的。

【讨论】:

  • 您好,谢谢您的回答!当我尝试这种方法时,我仍然收到错误:无法将 'const Something' 转换为 'Something*'。我不能说我对这些模板类型的工作方式太熟悉了,但我已经尝试改变正在传递的内容,我似乎所能做的就是导致更多错误。有什么想法吗?
猜你喜欢
  • 2021-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多