C4512 assignment operator could not be generated

Viewed 134

I'm working on updating an old C++ application, it is being compiled with MSVC 2013, not the latest I know.

I'm getting a warning:

1>c:\fraenkelsoftware-millikan\shared\debug\debughelper.h(84): warning C4512: 'HowLong' : assignment operator could not be generated
1>          c:\fraenkelsoftware-millikan\shared\debug\debughelper.h(65) : see declaration of 'HowLong'

Here is the class prototype:

class HowLong {
public:
    /// \param  Duration of what we are trying to measure
    HowLong(const std::string &a_str, IDebug::Severity a_sev = Sev_Debug):
            m_start(boost::posix_time::microsec_clock::universal_time()),
                m_str(a_str), m_sev(a_sev) {
    }
    /// Destructor outputs how long the object was alive
    ~HowLong() {
        boost::posix_time::time_duration elapsed(boost::posix_time::microsec_clock::universal_time() - m_start);
        DEBUG_LOG(m_sev, m_str + " took: " + boost::posix_time::to_simple_string(elapsed));
    }

private:
    const boost::posix_time::ptime m_start; ///< Start time
    const std::string m_str;                ///< Duration of what we are trying to measure
    const IDebug::Severity m_sev;
};

I haven't seen this warning before and I'm not sure what it actually means?

2 Answers

The class has constant private data members

const boost::posix_time::ptime m_start; ///< Start time
const std::string m_str;                ///< Duration of what we are trying to measure
const IDebug::Severity m_sev;

You may not reassign constant objects. So the compiler issues a message that it is unable to generate a default copy assignment operator that makes member-wise assignments.

Different example, similar effect:

struct foo { const int x = 42;};

int main() {
    foo f,g;
    f = g;
}

foo has no compiler generated assignment operator, because you cannot assign to a const member.

However, in the above it is causing an error (g cannot be assigned to f). I have to admit, that I have no clue how to get a warning only and I suppose the code that actually does trigger the warning is not in the part you posted.

Related