Я вижу, что есть еще один пост с почти таким же названием, прочитав его, я не понимаю ответа, может ли кто-нибудь мне помочь?
У меня есть проект, который изначально был разработан с использованием MSV C 2008, мне было поручено перенести его на MSV C 2017.
Я получаю следующую ошибку:
Severity Code Description Project File Line Suppression State
Error C2280 'Fraenkel::CommandDataField &Fraenkel::CommandDataField::operator =(const Fraenkel::CommandDataField &)': attempting to reference a deleted function Master Communications Service Group c:\fraenkelsoftware-millikan\core\service groups\master communications\code\command.cpp 125
Это функция, которая встречается в:
bool Command::getParameter(Fraenkel::CommandDataFieldIndex pos, Fraenkel::CommandDataField& param) const
{
// lock our list
std::lock_guard<std::mutex> lock(m_parametersMutex);
if (pos >= m_parameters.size())
{
return false;
}
param = m_parameters[pos]; //This is line 125
return true;
}
Fraenkel - это пространство имен, CommandDataField - это класс:
class CommandDataField
{
public:
/// Default c'tor
CommandDataField(void) {}
/// Default d'tor. No clean up is required.
~CommandDataField(void) {}
/// Copy constructor. Forwards to the universal constructor.
CommandDataField(const CommandDataField& source) : CommandDataField(source.m_val) {}
/// Move constructor. Forwards to the universal constructor.
CommandDataField(CommandDataField&& source) : CommandDataField(std::move(source.m_val)) {}
/// Constructor from byte vector. Forwards to ByteArray.
CommandDataField(std::vector<uint8_t> source) : CommandDataField(ByteArray(std::move(source))) {}
/// Templated c'tor. Sets the variant with the given value.
/// Note that T&& here is what Scott Myers calls a "universal reference".
/// You can't reliably overload a function once you've got a universal
/// reference in the mix, for reasons which are too involved to go into
/// here. So following a suggestion of Myers, we forward rvalue and lvalue
/// references separately to private constructors and do the specialisation
/// there.
template<typename T> explicit CommandDataField(T&& t) : CommandDataField(std::forward<T>(t), std::is_rvalue_reference<T&&>()) {}
/// Test whether the command data field is of a given type.
/// \return True if held variant's type matches the template argument
template<typename T>
bool isType(void) const
{
return (which() == CDFIndexOf<T>::value);
}
/// Test whether the command data field is of the same type as some other.
/// \param other Another CommandDataField to check
/// \return True if the two command data fields contain the same type
bool isType(const CommandDataField& other) const
{
return (which() == other.which());
}
/// Array and scalar conversion are sufficiently different that we can't
/// specialise directly, but we can dispatch through a mini-traits class.
template<typename T> struct Getter
{
static T get(const CommandDataField& cdf) { return cdf.get_s<T>(); }
};
/// It is sometimes convenient to get the CommandDataField itself as a
// no-op.
template<> struct Getter<CommandDataField>
{
static CommandDataField get(const CommandDataField& cdf) { return cdf; }
};
/// Variant list is really a scalar, since it corresponds to the value
/// stored directly in the data field.
template<> struct Getter<CDFVariantList>
{
static CDFVariantList get(const CommandDataField& cdf) { return cdf.get_s<CDFVariantList>(); }
};
/// And the vector version.
template<typename T> struct Getter<std::vector<T> >
{
static std::vector<T> get(const CommandDataField& cdf) { return cdf.get_v<T>(); }
};
/// Generic get method that works with array or scalar parameters.
template<typename T> T get(void) const { return Getter<T>::get(*this); }
/// get template method returns the value of the variant.
/// \return The value of the variant
template <typename T>
T get_s(void) const
{
if (typeid(T) != m_val.type())
{
throw std::logic_error("CommandDataField: wrong type for get");
}
const T *pX = boost::get<T>(&m_val);
return *pX;
}
/// Specialisation of get() for array types. WARNING slow for large arrays.
template<typename T> std::vector<T> get_v(void) const
{
const CDFVariantList* vs = boost::get<CDFVariantList>(&m_val);
assert(vs != nullptr);
std::vector<T> result;
result.reserve(vs->size());
for (auto const& v : *vs)
{
const T* val = boost::get<T>(&v);
assert(val != nullptr);
result.push_back(*val);
}
return result;
}
/// Set template method changes the value of the variant.
/// \param t Data to set. Must be one of the variant's supported types.
template <typename T> void set(const T& t) { m_val = t; }
/// returns the size of the stored array (and will assert if there is no array stored)
/// \return size
size_t getArraySize(void) const
{
assert(m_val.type() == typeid(ByteArray));
return get_s<ByteArray>().size();
}
/// Overload of set for handling lumps of binary data
/// which we will treat as lists of uint8_t's
/// \param pData Pointer to binary data
/// \param size Size in bytes of pData
void set(const uint8_t* pData, const size_t size)
{
ByteArray temp(size);
memcpy(temp.m_data.data(), pData, size);
m_val = std::move(temp);
}
/// Specialisation for array types (slow for large arrays)
template<typename T> void set(const std::vector<T>& t)
{
CDFVariantList temp;
temp.reserve(t.size());
std::copy(t.begin(), t.end(), std::back_inserter(temp));
m_val = temp;
}
/// Uber-specialisation for CDFVariantList, which can be set directly.
void set(const CDFVariantList& t) { m_val = t; }
/// Move version of the variant-list setter.
void set(CDFVariantList&& t) { m_val = std::move(t); }
/// Comparison operator: compares the underlying variants.
/// Boost will provide operator!= automatically thanks to the
/// equality_comparable template.
/// \param rhs Comparand.
/// \return true if the two fields are equal (type and value).
bool operator==(const CommandDataField& rhs) const
{
return (m_val == rhs.m_val);
}
/// Provides a means of accessing the underlying variant so that the visitor
/// pattern can be used. See boost::apply_visitor.
/// \param visitor A boost::static_visitor
/// \return Visitor-appropriate return value
template <typename Visitor>
typename Visitor::result_type applyVisitor(Visitor& visitor) const
{
return boost::apply_visitor(visitor, m_val);
}
/// Visitor, const version.
/// \param visitor A boost::static_visitor
/// \return Visitor-appropriate return value
template<typename Visitor>
typename Visitor::result_type applyVisitor(const Visitor& visitor) const
{
return boost::apply_visitor(visitor, m_val);
}
private:
/// Generic constructor for lvalue references; copies into the underlying
/// variant.
template<typename T> explicit CommandDataField(const T& t, std::false_type) : m_val(t) {}
/// Generic constructor for rvalue references; moves into the underlying
/// variant.
template<typename T> explicit CommandDataField(T&& t, std::true_type) : m_val(std::forward<T>(t)) {}
/// Vector constructor; forwards to set().
template<typename T> explicit CommandDataField(const std::vector<T>& v, std::false_type) { set(v); }
/// Rvalue vector constructor; forwards to set() (this won't be any
/// different from the lvalue version except in the case of a variant list,
/// which can be set directly).
template<typename T> explicit CommandDataField(std::vector<T>&& v, std::true_type) { set(std::move(v)); }
/// Alternative copy constructor for copy operations that were erroneously
/// caught by the universal constructor, because C++.
explicit CommandDataField(const CommandDataField& rhs, std::false_type) : m_val(rhs.m_val) {}
/// Get the type as an index into the list. Not for user consumption: is
/// used for type checking.
/// \return The list index of the given variant type
int which(void) const { return m_val.which(); }
CDFVariant m_val; ///< The variant that this class wraps.
};