Can't reserve a <vector> of a class object (complier error)

I have two classes WxMonth and WxWatch, the first containing a <vector> of the second. In the header file, I can declare:

std::vector<WxWatch> mMonthWx;

but when I attempt to set

mMonthWx.reserve(30);

in the class WxMonth constructor, I get an incomprehensible (at least to me) series of errors beginning with:

>D:\Programs\Visual Studio 2019\VC\Tools\MSVC\14.20.27508\include\xmemory0(819): error C2558: class 'WxWatch': no copy constructor available or copy constructor is declared 'explicit'
1>D:\Programs\Visual Studio 2019\VC\Tools\MSVC\14.20.27508\include\xmemory(141): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,_Ty>(_Alloc &,_Objty *const ,_Ty &&)' being compiled
1> with
1> [
1> _Alloc=std::allocator<WxWatch>,
1> _Ty=WxWatch,
1> _Objty=WxWatch
1> ]


If I comment out the reserve line, my code complies and runs, although it does nothing useful, yet. I have defined and implemented a WxWatch copy constructor and copy assignment and it is not explicit (unless somehow it's implicitly explicit).

Code below.

WxWatch.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#pragma once

#include <string>
#include <string_view>
#include <vector>
#include <iostream>

const int kWatchParams = 5;		//!< The number of strings that describe a watch.

enum kWxData
{
	WindDir,					//!< Wind Direction string
	WindStr,					//!< Wind Strength string
	Cloud,						//!< Cloud Cover string
	Precip,						//!< Precipitation string
	Temperature					//!< Temperature string
};

/*! \brief A class representing the weather for a watch.

 This class describes the weather for a single watch, the basic unit of weather tracking.
 The weather is described by the variables of wind direction and strength, precipitation,
 cloud cover, and temperature.  These data are stored in a vector of strings for easy
 maintenance and memory management. */

class WxWatch
{
public:
	WxWatch();
	WxWatch(const std::vector<std::string>);
	WxWatch(WxWatch&);
	WxWatch& operator=(const WxWatch&);

	virtual ~WxWatch();

	friend std::ostream& operator<<(std::ostream&, const WxWatch&);

	virtual std::string getWindDirection() const;
	virtual std::string getWindStrenth() const;
	virtual void setWind(const std::string_view, const std::string_view);

	virtual std::string getCloudCover() const;
	virtual void setCloudCover(const std::string_view);

	virtual std::string getPrecipitation() const;
	virtual void setPrecipitation(const std::string&);

	virtual std::string getTemperature() const;
	virtual void setTemperature(const std::string&);

	virtual std::vector<std::string> getWatch() const;

private:
	std::vector<std::string> mWatchWx;	//!< A vector of strings with the watch data
};

class WxMonth
{
public:
	WxMonth();
	virtual ~WxMonth() = default;

private:
	std::vector<WxWatch> mMonthWx;
};


WxWatch.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "pch.h"
#include "WxWatch.h"
// #include <vector>

using namespace std;

/*! \brief Default constructor.

This constructor sizes the watch vector and sets all strings to "Nil".  It uses the
kWatchParams constant to size the vector correctly.
*/
WxWatch::WxWatch()
{
	mWatchWx.reserve(kWatchParams);
	mWatchWx.assign(kWatchParams, "Nil");
}

/*! \brief Vector constructor

This constructor takes a correctly formated vector of strings to create a WxWatch object.
@param inWx is a vector<string> containing the watch data.
@warning No error checking is performed on the input string.
*/
WxWatch::WxWatch(const vector<string> inWx)
{
	mWatchWx = inWx;
}

/*! \brief Copy constructor

A standard copy constructor that copies another WxWatch object.
@param rhs is the WxWatch object that is copied.
*/
WxWatch::WxWatch(WxWatch& rhs)
{
	mWatchWx = rhs.mWatchWx;
}

/*! \brief Copy assignment

A standard copy assignment function that copies another WxWatch object.
@param rhs is the WxWatch object that is copied.
*/
WxWatch& WxWatch::operator=(const WxWatch& rhs)
{
	if (this == &rhs)
	{
		return *this;
	}
	mWatchWx = rhs.mWatchWx;
	return *this;
}

WxWatch::~WxWatch()
{
}

<snipped a bunch of simple getter/setter functions for the sake of length>

/*! \brief Watch output function

Output a Watch's data members directly to the console by overriding the << operator.
@return A reference to the output stream.
@param [in] os A reference to the output stream.
@param [in] inWatch A constant reference to the Watch to output
*/
ostream& operator<<(ostream & os, const WxWatch& inWatch)
{
	cout << "Watch Weather\n\n";
	cout << "Wind: " << inWatch.getWindStrenth() << " from the " << inWatch.getWindDirection();
	cout << "\nCloud:  " << inWatch.getCloudCover() << "\tPrecip:  " << inWatch.getPrecipitation();
	cout << "\nTemp:  " << inWatch.getTemperature() << "\n----------------------------\n";

	return os;
}

WxMonth::WxMonth()
{
	mMonthWx.reserve(30);
}
Last edited on
I don't know if this is the cause but your copy ctor should be:
 
WxWatch(const WxWatch&);

@dutch, You're correct.

Compilers will be rather picky about const being there (it's supposed to be required).

Otherwise, it just a constructor taking another WxWatch &, which does seem similar enough, but....
@dutch, @Niccolo

Thank you, both. Solved. That was the problem.
Topic archived. No new replies allowed.