【问题标题】:Specialize a template class to behave like a float in one case在一种情况下,特化一个模板类以使其表现得像一个浮点数
【发布时间】:2018-01-25 17:41:52
【问题描述】:

所以,想象一个向量类:

template <size_t size>
class Vector<size> {
    std::array<float, size> data;
    .... 
}

如果大小为 1,有没有办法将模板专门化为浮点数? 比如:

// The case of a Vector with size 1 should behave like a float
template <>
using class Vector<1> = float; 

我也想将其应用于其他课程。 例如,将列大小为 1 的 Matrix 视为具有行大小的 Vector。


提前感谢您的帮助:)

【问题讨论】:

  • 你试过犰狳arma.sourceforge.net 吗?
  • 我不知道您是否可以将Vector&lt;1&gt; 设为float 的别名,但您可以拥有一个仅适用于Vector&lt;1&gt; 的operator float&amp;。
  • @Minor Threat 我正在编写自己的数学库,用于教育、学习和玩耍,但感谢您的建议。
  • 添加一个operator float&amp; 很好。用float 替换整个东西是个坏主意。如果Vector&lt;2&gt;::size() 存在,那么Vector&lt;1&gt;::size() 也应该存在。

标签: c++ templates alias template-specialization


【解决方案1】:

您可以使用专用模板进行类型选择(请注意,别名模板不允许部分特化,因此无法仅使用一个模板):

template<size_t size> struct
VectorType{ using type = VectorImpl<size>; }; // VectorImpl is your current Vector

template<> struct
VectorType<1>{ using type = float; };

// alias template
template<size_t size> using
Vector = typename VectorType<size>::type;

【讨论】:

  • 谢谢,这似乎工作得很好。我想我只是希望有一个更短的解决方案,就像我最初问题中的一个想法一样。
【解决方案2】:

我现在无法检查。可能是下面这样的方式。

template <>
class Vector<1> {
  float n;
 public:
  operator float& () { return n; }
}

可能您需要实现其他必需的运算符。

【讨论】:

  • 对我来说似乎是一种可能性,谢谢。但是,它仍然会调用接受任意大小 Vector 的函数,而不是调用带有浮点数的重载版本,对吗?
  • 我不确定。我假设在这种情况下可以报告歧义错误。或者应该选择精确的浮点匹配,而不是任何大小的向量的模板函数。
  • 它确实会调用接受Vector(如果可用)的函数。对于存在完全匹配的情况,它不会进行隐式转换。
  • @patatahooligan 谢谢,我希望减少一些性能损失并简化一些事情,我想我必须采用 VTT 的解决方案。
  • @SirHeadshot:这个想法不会造成性能损失。你一定是有其他原因造成的。
【解决方案3】:

您的原始代码可能会违反One-Definition Rule,但我相信这可能是相当等效且相对较短的替代方案:

template <std::size_t N>
struct VectorImpl {
   std::array<float, N> data;
};

template <std::size_t N>
using Vector = typename std::conditional<(N == 1), float, VectorImpl<N>>::type;

[live demo]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多