当我们定义模板时,始终定义“value_type”是否是一种好的做法

Is it a good practice to always define `value_type` when we define a template

本文关键字:定义 是否是 一种 我们 value type      更新时间:2023-10-16
template<typename T>
class Point
{
public:
    typedef T value_type;
    ...
};

我在 Ray Lischner 的《简而言之C++》一书中看到了上面的代码,第 176 页。

问题:

  1. 始终添加value_type的定义是否是一种好的做法?
  2. 将在哪里使用这个定义的value_type

例如:Point<int>::value_type

拥有一个并

没有什么坏处,但它大多只对容器(如std::vector(有意义,因为所有容器都提供此typedef和统一的接口来访问包含的值( begin/endfront/back (,尽管这在 C++11 中大部分已经过时了autodecltype。不过,说some_template<typename container::value_type> ...还是更干净。

这反过来意味着它们可以在通用代码中互换使用(这是以这种方式完成工作的主要原因(。如果您的Point类知道包含的值是什么类型是有意义的,那么,请typedef.正如我所说,它没有伤害。但是,我有一种感觉,对于该特定示例来说,这没有太大意义。

编写在容器上执行的函数是一种很好的做法。 例如,如果我编写了一个接受容器(模板化(和两个要交换的索引的 swap 函数,那么我可以使用 value_type 定义来定义一个 temp 变量。

 template<typename T>
 void swap(T &container, int i, int j) {
    typename T::value_type temp = container[i];
    container[i] = container[j];
    container[i] = temp;
 }

我会说只有当它对类型有意义时。我遇到了麻烦,value_type妨碍了,因为某些通用算法错误地假设它是某种容器(就我而言,我似乎记得它是 boost 中的某种算法,假设shared_ptr是一个容器多项目容器由于存在value_type(。

我相信为

点的坐标类型提供value_type定义绝对是有意义的。通过这种做法,您可以定义自己的概念,如何定义点类型,这非常有用,因为您可以开发如下模板化算法:

template <class TPoint>
struct Algorithms
{
   TPoint::value_type SmallestCoordinate(const std::vector<TPoint>& points);
   std::vector<TPoint> SelectPoints(const std::vector<TPoint>& points,
                                    std::vector<typename TPoint::value_type> thresholds);
}

如果您定义了一个描述良好的概念,则这些算法可以独立于点类实现,该概念应提供什么。例如:

  • operator[](size_t i)提供点的第i个坐标
  • size()返回维度(坐标(的数量。
  • value_type提供坐标类型。

这意味着您可以拥有自己的MyPoint实现:

template<typename T>
class Point
{
public:
    using value_type = T;
    value_type x{};
    value_type y{};
    size_t size()
    {
        return 2u;
    }
    value_type operator[](size_t i)
    {
        switch(i)
        {
            case 0: return x;
            case 1: return y;
            default: throw std::out_of_range();
        }
    }
};

或者你也可以使用它:

template <typename T>
using Point = std::array<T, 2>;

上面定义的算法同样工作得很好。