【发布时间】:2020-02-07 23:12:04
【问题描述】:
我正在研究一个高度模板化的数学向量类。它的维度和组件的类型都是这样模板化的。
#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*' : no global operator found which take type 'Math::Vector' (或没有可接受的转换)”
#include "Vector.h"
#include <stdio.h>
int main()
{
Math::Vector<2> v1 = Math::Vector<2>(2, 3);
v1 = 2 * v1;
return 0;
}
我应该怎么做才能完成这项工作?
【问题讨论】:
-
请提供与错误消息匹配的minimal reproducible example。您发布的代码中没有
Math -
为了这个问题,您可以将
Math::Vector替换为std::vector以纯粹测试您的模板化方式。 -
@bloody 这不是 std::vector。这是我自己实现的数学向量。
-
@SangWanJeon 虽然这对你提出的问题并不重要。虽然您编辑问题以包含代码是件好事,但您没有尊重一个好问题的要求之一:包含 minimal 代码。您包含的代码包含许多与此处无关的内容。
-
@KonradRudolph 我编辑了两次,第一次是包含代码,第二次是最小化它。我想你正在看第一个。很抱歉给您带来不便,但您可以重新加载问题吗?
标签: c++ templates operator-overloading