Jehjoa Jehjoa - 2 months ago 7
C++ Question

Code that compiled fine in MSVC2013 seems to confuse MSVC2015

I'm trying to migrate my development environment from Visual Studio 2013 to 2015, and I'm running into a weird issue with one of my projects. The compiler somehow seems to think I'm trying to reference a deleted move constructor while I'm actually trying to use a regular constructor to throw an instance of a class.

I'm writing a thin wrapper around libcurls HTTP capabilities. Here's one example of a compilation error I'm getting. I'm getting two more of these in similar but different parts of the code.

1>e:\code\win32\contentwatcher\contentwatcher\http_client.cpp(18): error C2248: 'http::curl_error::curl_error': cannot access private member declared in class 'http::curl_error'
1> e:\code\win32\contentwatcher\contentwatcher\http_client.hpp(19): note: see declaration of 'http::curl_error::curl_error'
1> e:\code\win32\contentwatcher\contentwatcher\http_client.hpp(16): note: see declaration of 'http::curl_error'


This is the relevant part of http_client.hpp:

namespace http {

class curl_error : public std::runtime_error ////////////////// LINE 16
{
curl_error(const curl_error &) = default;
curl_error(curl_error &&) = delete; /////////////////////// LINE 19
curl_error &operator=(const curl_error &) = delete;
curl_error &operator=(curl_error &&) = delete;
public:
curl_error(const char *message, CURLcode cc);
curl_error(CURLcode cc);
~curl_error() = default;
protected:
private:
CURLcode m_code;
std::string m_details;
};

class curl_init
{
curl_init(const curl_init &) = delete;
curl_init(curl_init &&) = delete;
curl_init &operator=(const curl_init &) = delete;
curl_init &operator=(curl_init &&) = delete;
public:
curl_init(long flags = CURL_GLOBAL_DEFAULT);
~curl_init() = default;
protected:
private:
};

} // namespace http


And the relevant part of http_client.cpp where the actual compilation error occurs:

http::curl_init::curl_init(long flags)
{
auto cc = curl_global_init(flags);
if (cc != CURLE_OK) throw curl_error{ cc }; /////////////// LINE 18
}


As you can see I'm just trying to construct a
curl_error
object in order to throw it as an exception. Worked fine in MSVC2013 but 2015 seems to think I'm trying to move-construct it?

I have no idea what's wrong here, or which keywords to Google to solve this... Thanks in advance for any pointers.

Answer

In the C++ language spec, when talking about the throw statement, it says, "Throwing an exception copy-initializes a temporary object, called the exception object." So the exception object you're throwing needs to be copyable.

Since you're copy constructor is private, it is not accessible. You need to make it public and implement it.