0lakan0 0lakan0 - 3 months ago 35
C++ Question

std::copy: operator= not found

I'm having a problem when using std::copy on Vector_t's initializer_list constructor. But as you can see in FixedPoint_t's declaration it has sufficient declarations for copy-construction and assignment. What signature does the compiler expect of me? Or am I missing something here? The compiler output points out that FixedPoint_t's operator= might fit, but it's still not used. There seems to be an issue with matching the argument list, too.

What I've tried:
Vector_t works for integral types and other classes, so it has to be some problem with FixedPoint_t.

The MSDN page indicates a missing constructor. But FixedPoint_t's ctor matches.

FixedPoint_t's are assignable outside of Vector_t, but I can't draw a conclusion of it.

I could not reproduce the error with an int-wrapper I made.

Compiler: VS Compiler (VS 2015)

Error: C2679 Binary operator "=": No operator was found with rhs argument of type "const math::FixedPoint_t" (or no adequate conversion is possible)

Test Code



#include <FpMath/FpMath.hpp>

using namespace math;

int main(int argc, char** argv) {

// Vector object construction using an initializer_list
Vector_t<FixedPoint_t<int, 4096>, 1> vec {
4096
};

// Assignment outisde of Vector_t
FixedPoint_t<int, 4096> fp1(3 * 4096);
FixedPoint_t<int, 4096> fp2 = fp1; // works

return 0;
}


Vector.hpp



#pragma once

#include <array>
#include <cassert>
#include <initializer_list>
#include <algortihm> // std::copy

#include "FixedPoint.hpp"

namespace math {

template <typename T, size_type size>
class Vector_t {
public:

typedef T value_type;

Vector_t(std::initializer_list<value_type> li);

...

private:

std::array<value_type, size> m_values;
};

template <typename T, size_type size>
Vector_t<T, size>::Vector_t(std::initializer_list<value_type> li) : m_values() {

assert(li.size() <= size);
std::copy(li.begin(), li.end(), m_values.begin()); // < Error occurs here
}
}


FixedPoint.hpp



#pragma once

#include <cassert>
#include <limits>

namespace math {

template <typename T, T denom>
class FixedPoint_t {
public:

typedef T value_type;
typedef class_type& reference;

FixedPoint_t();
FixedPoint_t(const value_type& numerator);
FixedPoint_t(const reference other);

inline reference operator=(const reference other);
inline reference operator=(const value_type& val);
};
}

Answer

The problem is here:

typedef class_type& reference;
...
FixedPoint_t(const reference other);
...
inline reference operator=(const reference other);

This construction does not declare const reference parameters. Change this to

typedef class_type& reference;
typedef const class_type& const_reference;
...
FixedPoint_t(const_reference other);
...
inline reference operator=(const_reference other);