0

Book and Article are derived classes from Medium.

Why am I getting this error when trying to insert Medium / Book / Article in the bibliography?

error: no matching function for call to '**std::reference_wrapper<Medium>::reference_wrapper()**

Compiler error

main.cc

#include <iostream>
using namespace std;
#include "Bibliography.h"
#include "Medium.h"
#include "Book.h"
#include "Article.h"

int main()
{
    Bibliography p(1);
    Medium m1("PN","I","Pasol nah",2017);
    p.insert(m1);
    cout << p;
    return 0;
}

Bibliography.h

#ifndef BIBLIOGRAPHY_H_
#define BIBLIOGRAPHY_H_

#include "Medium.h"
#include "Article.h"
#include "Book.h"
#include <iostream>
#include <functional>
#include <vector>

class Bibliography
{
  private:
    int m_Size;
    std::vector<std::reference_wrapper<Medium>> v;
    int index;
  public:
    Bibliography(int size);
    void insert(Medium m);
    friend std::ostream& operator<<(std::ostream& out, const Bibliography &b1);
};

#endif

Bibliography.cc

#include "Bibliography.h"

Bibliography::Bibliography(int size)
{
    std::cout << "Bibliography created \n";
    m_Size = size;
    v.resize(m_Size);
    index = 0;
}

void Bibliography::insert(Medium m)
{
    v.push_back(m);
}

std::ostream& operator<<(std::ostream& out, const Bibliography &b1)
{
    for (Medium &Medium : b1.v)
    {
        out << Medium.toString() << std::endl;
    }
    return out;
}
Parker
  • 7,244
  • 12
  • 70
  • 92
Gicu Mironica
  • 585
  • 8
  • 22

1 Answers1

3

You should not use reference_wrapper in vector, because vector is restricted when using it with classes that do not have a default constructor. reference_wrapper doesn't have it, look at these constructors of reference_wrapper:

// initialization (1)   
reference_wrapper (type& ref) noexcept;
reference_wrapper (type&&) = delete;
// copy (2) 
reference_wrapper (const reference_wrapper& x) noexcept;

In this line

v.resize(m_Size); 

you want to create m_Size reference_wrapperobjects, but the default constructor for reference_wrapper doesn't exist, and code cannot be compiled.

You can use reference_wrapper with vector but you will get a compilation error when a method of vector is called, that needs the default constructor to be defined.

Xerusial
  • 525
  • 1
  • 5
  • 17
rafix07
  • 20,001
  • 3
  • 20
  • 33
  • 1
    Is this really true? The C++ Reference specifically [uses a vector](https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper) as the example usage of a `reference_wrapper`. – Parker Nov 25 '18 at 14:23
  • 1
    In the example you posted there is a list with 10 elements. `list l(10);` vector keeps `reference_wrapper`, when this vector is created `v(l.begin(),l.end())` constructor of `reference_wrapper` is called which takes Lvalues as parameter, storing pointer to these Lvalues, so in this case vector+reference_wrapper works. But `resize` on vector cannot be called because `resize` calls default ctor for `reference_wrapper`. `reference_wrapper` needs to store pointer to some object (reference needs to be initialized). Therefore default ctor for reference_wrapper doesn't exist. – rafix07 Nov 25 '18 at 14:43
  • Much appreciated. The C++ Reference would be more helpful if it included examples like this. – Parker Nov 25 '18 at 15:00