在定义模板时始终定义`value_type`是一个好习惯

时间:2012-03-09 15:58:41

标签: c++

template<typename T>
class Point
{
public:
    typedef T value_type;
    ...
};

我在书"C++ in a Nutshell" by Ray Lischner, pp176中看到了上述代码。

问题:

  1. 始终添加value_type
  2. 的定义是一种好习惯
  3. 这个定义value_type将在哪里使用?
  4. 例如:Point<int>::value_type

4 个答案:

答案 0 :(得分:18)

拥有一个没有坏处,但它主要只对容器(如std::vector)有意义,因为所有容器都提供此typedef和一个用于访问包含值的统一接口({ {1}} / beginend / front),尽管在{+ 1}}和back的C ++ 11中大部分已经过时了。尽管如此,说auto仍然更清晰。

这反过来意味着它们可以在通用代码中互换使用(事情以这种方式完成的主要原因)。如果您的decltype类知道所包含的值的类型是有意义的,那么就有some_template<typename container::value_type> ...。正如我所说,它并没有伤害。但是,我觉得这个特定的例子并没有多大意义。

答案 1 :(得分:7)

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

 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;
 }

答案 2 :(得分:1)

我只会说这种类型有意义。我遇到了一些问题,其中value_type妨碍了,因为一些通用算法错误地认为它是某种容器(在我的情况下,我似乎记得它是boost中的一些算法,假设shared_ptr是一个容器多项容器,由于value_type存在)。

答案 3 :(得分:0)

我相信为该点的坐标类型提供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>;

上面定义的算法工作类似。