Я работаю над сильно математическим классом Vector. Его размер и тип компонентов настроены следующим образом.
#pragma once
#include <array>
#include <type_traits>
#include <cassert>
namespace Math
{
template <size_t D, typename T = double>
class Vector
{
//
// Template Assertions
//
static_assert(D > 0, "Dimension of an Vector must be bigger than 0");
static_assert(std::is_arithmetic<T>::value, "Component Type of Vector must be Arithmetic");
//
// Template Typedefs
//
template <typename... > struct typelist;
//
// Private Variables
//
std::array<T, D> _components;
Vector(std::array<T, D> components) : _components(components), dimension(D)
{
static_assert(components.size() == D, "Component Count must match Dimension");
}
public:
//
// Public Variables
//
const size_t dimension;
//
// Constructors
//
template <typename ...Args, typename = std::enable_if_t<!std::is_same<typelist<Vector>, typelist<std::decay_t<Args>...>>::value>>
Vector(Args&&... args) : _components{ T(args)... }, dimension(D)
{
static_assert(sizeof...(Args) == D, "Component Count must match Dimension");
}
Vector(const Vector &t) : _components(t._components), dimension(t.dimension)
{
assert(t.dimension == D);
}
//
// Operators
//
Vector& operator=(const Vector& other)
{
if (this != &other) {
_components(other._components);
dimension = other._components.size();
}
return *this;
}
T& operator[](const size_t index)
{
return _components[index];
}
const T& operator[](const size_t index) const
{
return _components[index];
}
};
//
// Operators
//
typedef Vector<2> Vector2;
typedef Vector<3> Vector3;
template<size_t D, typename T, typename K, std::enable_if_t<std::is_arithmetic<K>::value>>
Vector<D, T> operator*(const K& lhs, Vector<D, T>& rhs) {
Vector<D, T> vec = Vector<D, T>(rhs);
for (size_t i = 0; i < vec.dimension; ++i)
{
vec[i] = vec[i] * lhs;
}
return vec;
}
}
Я хочу, чтобы каждый арифметический тип (Arithmetic_Type с std::is_arithmetic<T>::value == true
) имел operator*
для работы с моим пользовательским классом. Поэтому я попробовал эту operator*
подпись вне класса.
template<size_t D, typename T, typename K, std::enable_if_t<std::is_arithmetic<K>::value>>
Vector<D, T> operator*(const K& lhs, Vector<D, T>& rhs) {
Vector<D, T> vec = Vector<D, T>(rhs);
for (size_t i = 0; i < vec.dimension; ++i)
{
vec[i] = vec[i] * lhs;
}
return vec;
}
Он хорошо компилируется, но если я пытаюсь использовать их таким образом, он не находит operator*
.
(Так как я использую Visual Studio, код ошибки - C2677, "двоичный"'operator *': не найден глобальный оператор, который принимает тип 'Math :: Vector <2U, double>' (или нет приемлемого преобразования) "
#include "Vector.h"
#include <stdio.h>
int main()
{
Math::Vector<2> v1 = Math::Vector<2>(2, 3);
v1 = 2 * v1;
return 0;
}
Что я должен сделать, чтобы эта работа работала?