【发布时间】:2021-08-28 02:11:55
【问题描述】:
所以,这不是我真正必须做的事情,我只是在玩。我为任何数字类型和任意数量坐标的向量编写了一个Vector 类。它用作Vector<NumericType, [num of coords]>。代码如下:
#include <array>
#include <functional>
namespace World {
template <typename NumType, unsigned char Size>
class Vector
{
public:
using CoordType = NumType;
template<typename... NumTypes>
constexpr Vector(NumTypes&&... vals) : values{ std::forward<NumTypes>(vals)... }
{
static_assert(sizeof...(NumTypes) == Size, "You must provide N arguments.");
}
Vector(const std::array<NumType, Size>& values) : values(values) {}
Vector(const std::array<NumType, Size>&& values) : values(std::move(values)) {}
const NumType& operator[](size_t offset) const { return values[offset]; }
NumType& operator[](size_t offset) { return values[offset]; }
//! Converts all values to new given type
template <typename NewType>
constexpr Vector<NewType, Size> Convert() const { return Convert<NewType>(std::make_index_sequence<Size>{}); }
//! Converts all values via the conversion function
template <typename NewType>
Vector<NewType, Size> Convert(const std::function<NewType(NumType)>& callback) const { return Convert<NewType>(std::make_index_sequence<Size>{}, callback); }
std::array<NumType, Size> values;
private:
//! Converts all values to new given type
template <typename NewType, std::size_t ... Is>
constexpr Vector<NewType, Size> Convert(std::index_sequence<Is...>) const { return { { static_cast<NewType>(values[Is])}... }; }
//! Converts all values via the conversion function
template <typename NewType, std::size_t ... Is>
Vector<NewType, Size> Convert(std::index_sequence<Is...>, const std::function<NewType(NumType)>& callback) const { return { { callback(values[Is])}... } ; }
};
现在我要做的是确保上面声明的转换函数正常工作。使用思路是这样的:
using namespace World;
using Vector3D = Vector<double, 3>;
using Vector3Int = Vector<int, 3>;
#include <cmath>
int main()
{
const Vector3D src{ 1.4, 2.5, 3.6 };
const Vector3Int target = src.Convert<int>([](double val) { return (int)std::round(val); });
return 0;
}
这里的问题是编译转换函数时,生成的新值以std::initializer_list<NewType>的形式出现。由于某种原因,这不符合构造函数Vector(NumTypes&&... vals) 的条件。现在我不想有一个初始化列表构造函数 - 预期参数的数量不是可变的,它必须是 Size 模板参数所说的任何内容。
那么如何解决这个问题?如何将 std::initializer_list 转换为 NumTypes&&... vals 是什么?
我必须在这里承认,我并不确切地知道我在做什么,我正在努力提高我的 C++ 知识。
【问题讨论】:
-
我没有仔细看,但是
Convert函数是否应该像这样返回:return { {callback(values[Is])... } } ;? -
OT:首先,常量右值引用没有意义(特别是,如果您稍后试图从它们“移动”)。其次,基本类型的完美转发也没有意义。对于
int或double这样的类型,复制和移动之间没有区别。 -
@TedLyngmo 成功了,你真是个天才!但是点的位置是基于其他代码,当它们位于括号后面时,它们会起作用......你能否发布一个答案来解释
{{x...}}和{{x}...}之间的区别? -
@TomášZato-ReinstateMonica Cool(简体:
return {callback(values[Is])...};也应该可以)。我写不出答案。 3小时的会议现在开始。我会把它留给别人。 :-) -
@TomášZato-ReinstateMonica 我看到没有人拿起球,所以我试图通过使用示例来解释它。我觉得我自己解释得不好,所以我希望其他人能做出更好的答案(或者如果可以挽救的话,可以改进我的答案)
标签: c++ templates c++17 variadic-templates initializer-list