-1

我想传递一个填充了基于对象的同一类的向量。两者std::reference_wrapper和无参考都不能解决它。解决这个问题的正确方法是什么?

class MyClass
{
public:
    MyClass(int){};
    virtual void print() const {
        std::cout<<"MyClass"<<std::endl;
    }
};
class MySubClass : public MyClass
{
public:
    MySubClass(int a):MyClass(a){};
    virtual void print() const {
        std::cout<<"MySubClass"<<std::endl;
    }
};
void test(const std::vector<std::reference_wrapper<MyClass>>& v)
{
    for (const auto& c : v) {
        c.get().print();
    }
}
void test(const std::vector<MyClass>& v)
{
    for (const auto& c : v) {
        c.print();
    }
}
int main() 
{
    {
        MySubClass s(2);
        std::vector<MyClass> v;
        v.push_back(s);
        test(v);//print MyClass, but I need MySubClass
    }
    {
        MySubClass s(2);
        std::vector<std::reference_wrapper<MyClass>> v;
        v.push_back(s);
        test(v);//print MySubClass
        test({2});
        test({s});//wrong ambigious
    }
    return 0;
}
4

1 回答 1

1
{
    MySubClass s(2);
    std::vector<MyClass> v;
    v.push_back(s);
    test(v);//print MyClass, but I need MySubClass
}

这里的问题是您试图将MySubClass对象存储在MyClass. 不可能存储整个MySubClass,而是只MyClass存储父子对象。这与您将存储的对象视为MySubClass实例的愿望相冲突。

{
    MySubClass s(2);
    std::vector<std::reference_wrapper<MyClass>> v;
    v.push_back(s);

这解决了前面的问题。引用可以引用其静态类型的子类。不过,请记住,对象并未存储在向量中。该对象存储为局部变量s,并且仅由向量引用。

    test(v);//print MySubClass
    test({2});
    test({s});//wrong ambigious

这里的问题是你有两个重载,它们都不接受 a MySubClass,但都接受可以从MySubClass. 因此,重载决议是不明确的。编译器不知道您打算调用哪个重载。

要么使用显式临时初始化而不是简单的初始化列表。

    test(std::vector<MyClass>{2});
    test(std::vector<std::reference_wrapper<MyClass>>{s});

或者不要使用重载,而是使用唯一命名的函数。

void test(const std::vector<std::reference_wrapper<MyClass>>& v)
void test2(const std::vector<MyClass>& v)
于 2017-01-04T08:50:27.123 回答