template<typename T>
class Point
{
public:
typedef T value_type;
...
};
我在 Ray Lischner 的《简而言之C++》一书中看到了上面的代码,第 176 页。
问题:
- 始终添加
value_type
的定义是否是一种好的做法? - 将在哪里使用这个定义的
value_type
?
例如:Point<int>::value_type
?
没有什么坏处,但它大多只对容器(如std::vector
(有意义,因为所有容器都提供此typedef
和统一的接口来访问包含的值( begin
/end
, front
/back
(,尽管这在 C++11 中大部分已经过时了auto
和decltype
。不过,说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>;
上面定义的算法同样工作得很好。